Merge branch 'develop' into matthewpi/security-keys-backport
This commit is contained in:
commit
f631ac1946
1153 changed files with 25099 additions and 37002 deletions
29
app/Transformers/Api/Application/AdminRoleTransformer.php
Normal file
29
app/Transformers/Api/Application/AdminRoleTransformer.php
Normal file
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Transformers\Api\Application;
|
||||
|
||||
use Pterodactyl\Models\AdminRole;
|
||||
use Pterodactyl\Transformers\Api\Transformer;
|
||||
|
||||
class AdminRoleTransformer extends Transformer
|
||||
{
|
||||
/**
|
||||
* Return the resource name for the JSONAPI output.
|
||||
*/
|
||||
public function getResourceName(): string
|
||||
{
|
||||
return AdminRole::RESOURCE_NAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform admin role into a representation for the application API.
|
||||
*/
|
||||
public function transform(AdminRole $model): array
|
||||
{
|
||||
return [
|
||||
'id' => $model->id,
|
||||
'name' => $model->name,
|
||||
'description' => $model->description,
|
||||
];
|
||||
}
|
||||
}
|
|
@ -2,18 +2,14 @@
|
|||
|
||||
namespace Pterodactyl\Transformers\Api\Application;
|
||||
|
||||
use Pterodactyl\Models\Node;
|
||||
use Pterodactyl\Models\Server;
|
||||
use League\Fractal\Resource\Item;
|
||||
use Pterodactyl\Models\Allocation;
|
||||
use League\Fractal\Resource\NullResource;
|
||||
use Pterodactyl\Services\Acl\Api\AdminAcl;
|
||||
use Pterodactyl\Transformers\Api\Transformer;
|
||||
|
||||
class AllocationTransformer extends BaseTransformer
|
||||
class AllocationTransformer extends Transformer
|
||||
{
|
||||
/**
|
||||
* Relationships that can be loaded onto allocation transformations.
|
||||
*/
|
||||
protected array $availableIncludes = ['node', 'server'];
|
||||
|
||||
/**
|
||||
|
@ -27,22 +23,21 @@ class AllocationTransformer extends BaseTransformer
|
|||
/**
|
||||
* Return a generic transformed allocation array.
|
||||
*/
|
||||
public function transform(Allocation $allocation): array
|
||||
public function transform(Allocation $model): array
|
||||
{
|
||||
return [
|
||||
'id' => $allocation->id,
|
||||
'ip' => $allocation->ip,
|
||||
'alias' => $allocation->ip_alias,
|
||||
'port' => $allocation->port,
|
||||
'notes' => $allocation->notes,
|
||||
'assigned' => !is_null($allocation->server_id),
|
||||
'id' => $model->id,
|
||||
'ip' => $model->ip,
|
||||
'alias' => $model->ip_alias,
|
||||
'port' => $model->port,
|
||||
'notes' => $model->notes,
|
||||
'server_id' => $model->server_id,
|
||||
'assigned' => !is_null($model->server_id),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the node relationship onto a given transformation.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Transformer\InvalidTransformerLevelException
|
||||
*/
|
||||
public function includeNode(Allocation $allocation): Item|NullResource
|
||||
{
|
||||
|
@ -50,17 +45,11 @@ class AllocationTransformer extends BaseTransformer
|
|||
return $this->null();
|
||||
}
|
||||
|
||||
return $this->item(
|
||||
$allocation->node,
|
||||
$this->makeTransformer(NodeTransformer::class),
|
||||
Node::RESOURCE_NAME
|
||||
);
|
||||
return $this->item($allocation->node, new NodeTransformer());
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the server relationship onto a given transformation.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Transformer\InvalidTransformerLevelException
|
||||
*/
|
||||
public function includeServer(Allocation $allocation): Item|NullResource
|
||||
{
|
||||
|
@ -68,10 +57,6 @@ class AllocationTransformer extends BaseTransformer
|
|||
return $this->null();
|
||||
}
|
||||
|
||||
return $this->item(
|
||||
$allocation->server,
|
||||
$this->makeTransformer(ServerTransformer::class),
|
||||
Server::RESOURCE_NAME
|
||||
);
|
||||
return $this->item($allocation->server, new ServerTransformer());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,114 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Transformers\Api\Application;
|
||||
|
||||
use Carbon\CarbonImmutable;
|
||||
use Carbon\CarbonInterface;
|
||||
use Illuminate\Http\Request;
|
||||
use Webmozart\Assert\Assert;
|
||||
use Pterodactyl\Models\ApiKey;
|
||||
use Illuminate\Container\Container;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use League\Fractal\TransformerAbstract;
|
||||
use Pterodactyl\Services\Acl\Api\AdminAcl;
|
||||
|
||||
/**
|
||||
* @method array transform(Model $model)
|
||||
*/
|
||||
abstract class BaseTransformer extends TransformerAbstract
|
||||
{
|
||||
public const RESPONSE_TIMEZONE = 'UTC';
|
||||
|
||||
protected Request $request;
|
||||
|
||||
/**
|
||||
* BaseTransformer constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
// Transformers allow for dependency injection on the handle method.
|
||||
if (method_exists($this, 'handle')) {
|
||||
Container::getInstance()->call([$this, 'handle']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the resource name for the JSONAPI output.
|
||||
*/
|
||||
abstract public function getResourceName(): string;
|
||||
|
||||
/**
|
||||
* Sets the request on the instance.
|
||||
*/
|
||||
public function setRequest(Request $request): self
|
||||
{
|
||||
$this->request = $request;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new transformer instance with the request set on the instance.
|
||||
*/
|
||||
public static function fromRequest(Request $request): BaseTransformer
|
||||
{
|
||||
return app(static::class)->setRequest($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the API key loaded onto the transformer has permission
|
||||
* to access a different resource. This is used when including other
|
||||
* models on a transformation request.
|
||||
*
|
||||
* @deprecated — prefer $user->can/cannot methods
|
||||
*/
|
||||
protected function authorize(string $resource): bool
|
||||
{
|
||||
$allowed = [ApiKey::TYPE_ACCOUNT, ApiKey::TYPE_APPLICATION];
|
||||
|
||||
$token = $this->request->user()->currentAccessToken();
|
||||
if (!$token instanceof ApiKey || !in_array($token->key_type, $allowed)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If this is not a deprecated application token type we can only check that
|
||||
// the user is a root admin at the moment. In a future release we'll be rolling
|
||||
// out more specific permissions for keys.
|
||||
if ($token->key_type === ApiKey::TYPE_ACCOUNT) {
|
||||
return $this->request->user()->root_admin;
|
||||
}
|
||||
|
||||
return AdminAcl::check($token, $resource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance of the transformer and pass along the currently
|
||||
* set API key.
|
||||
*
|
||||
* @template T of \Pterodactyl\Transformers\Api\Application\BaseTransformer
|
||||
*
|
||||
* @param class-string<T> $abstract
|
||||
*
|
||||
* @return T
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Transformer\InvalidTransformerLevelException
|
||||
*
|
||||
* @noinspection PhpDocSignatureInspection
|
||||
*/
|
||||
protected function makeTransformer(string $abstract)
|
||||
{
|
||||
Assert::subclassOf($abstract, self::class);
|
||||
|
||||
return $abstract::fromRequest($this->request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an ISO-8601 formatted timestamp to use in the API response.
|
||||
*/
|
||||
protected function formatTimestamp(string $timestamp): string
|
||||
{
|
||||
return CarbonImmutable::createFromFormat(CarbonInterface::DEFAULT_TO_STRING_FORMAT, $timestamp)
|
||||
->setTimezone(self::RESPONSE_TIMEZONE)
|
||||
->toAtomString();
|
||||
}
|
||||
}
|
|
@ -2,17 +2,15 @@
|
|||
|
||||
namespace Pterodactyl\Transformers\Api\Application;
|
||||
|
||||
use Pterodactyl\Models\Database;
|
||||
use Pterodactyl\Models\DatabaseHost;
|
||||
use League\Fractal\Resource\Collection;
|
||||
use League\Fractal\Resource\NullResource;
|
||||
use Pterodactyl\Services\Acl\Api\AdminAcl;
|
||||
use Pterodactyl\Transformers\Api\Transformer;
|
||||
|
||||
class DatabaseHostTransformer extends BaseTransformer
|
||||
class DatabaseHostTransformer extends Transformer
|
||||
{
|
||||
protected array $availableIncludes = [
|
||||
'databases',
|
||||
];
|
||||
protected array $availableIncludes = ['databases'];
|
||||
|
||||
/**
|
||||
* Return the resource name for the JSONAPI output.
|
||||
|
@ -33,16 +31,13 @@ class DatabaseHostTransformer extends BaseTransformer
|
|||
'host' => $model->host,
|
||||
'port' => $model->port,
|
||||
'username' => $model->username,
|
||||
'node' => $model->node_id,
|
||||
'created_at' => $model->created_at->toAtomString(),
|
||||
'updated_at' => $model->updated_at->toAtomString(),
|
||||
'created_at' => self::formatTimestamp($model->created_at),
|
||||
'updated_at' => self::formatTimestamp($model->updated_at),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Include the databases associated with this host.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Transformer\InvalidTransformerLevelException
|
||||
*/
|
||||
public function includeDatabases(DatabaseHost $model): Collection|NullResource
|
||||
{
|
||||
|
@ -50,8 +45,7 @@ class DatabaseHostTransformer extends BaseTransformer
|
|||
return $this->null();
|
||||
}
|
||||
|
||||
$model->loadMissing('databases');
|
||||
|
||||
return $this->collection($model->getRelation('databases'), $this->makeTransformer(ServerDatabaseTransformer::class), Database::RESOURCE_NAME);
|
||||
// TODO
|
||||
return $this->collection($model->databases, new ServerDatabaseTransformer());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,26 +2,23 @@
|
|||
|
||||
namespace Pterodactyl\Transformers\Api\Application;
|
||||
|
||||
use Illuminate\Support\Arr;
|
||||
use Pterodactyl\Models\Egg;
|
||||
use Pterodactyl\Models\Nest;
|
||||
use Pterodactyl\Models\Server;
|
||||
use League\Fractal\Resource\Item;
|
||||
use Pterodactyl\Models\EggVariable;
|
||||
use League\Fractal\Resource\Collection;
|
||||
use League\Fractal\Resource\NullResource;
|
||||
use Pterodactyl\Services\Acl\Api\AdminAcl;
|
||||
use Pterodactyl\Transformers\Api\Transformer;
|
||||
|
||||
class EggTransformer extends BaseTransformer
|
||||
class EggTransformer extends Transformer
|
||||
{
|
||||
/**
|
||||
* Relationships that can be loaded onto this transformation.
|
||||
*/
|
||||
protected array $availableIncludes = [
|
||||
'nest',
|
||||
'servers',
|
||||
'config',
|
||||
'nest',
|
||||
'script',
|
||||
'servers',
|
||||
'variables',
|
||||
];
|
||||
|
||||
|
@ -50,19 +47,14 @@ class EggTransformer extends BaseTransformer
|
|||
'id' => $model->id,
|
||||
'uuid' => $model->uuid,
|
||||
'name' => $model->name,
|
||||
'nest' => $model->nest_id,
|
||||
'nest_id' => $model->nest_id,
|
||||
'author' => $model->author,
|
||||
'description' => $model->description,
|
||||
// "docker_image" is deprecated, but left here to avoid breaking too many things at once
|
||||
// in external software. We'll remove it down the road once things have gotten the chance
|
||||
// to upgrade to using "docker_images".
|
||||
'docker_image' => count($model->docker_images) > 0 ? Arr::first($model->docker_images) : '',
|
||||
'docker_images' => $model->docker_images,
|
||||
'config' => [
|
||||
'files' => $files,
|
||||
'startup' => json_decode($model->config_startup, true),
|
||||
'stop' => $model->config_stop,
|
||||
'logs' => json_decode($model->config_logs, true),
|
||||
'file_denylist' => $model->file_denylist,
|
||||
'extends' => $model->config_from,
|
||||
],
|
||||
|
@ -74,43 +66,11 @@ class EggTransformer extends BaseTransformer
|
|||
'container' => $model->script_container,
|
||||
'extends' => $model->copy_script_from,
|
||||
],
|
||||
$model->getCreatedAtColumn() => $this->formatTimestamp($model->created_at),
|
||||
$model->getUpdatedAtColumn() => $this->formatTimestamp($model->updated_at),
|
||||
'created_at' => self::formatTimestamp($model->created_at),
|
||||
'updated_at' => self::formatTimestamp($model->updated_at),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Include the Nest relationship for the given Egg in the transformation.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Transformer\InvalidTransformerLevelException
|
||||
*/
|
||||
public function includeNest(Egg $model): Item|NullResource
|
||||
{
|
||||
if (!$this->authorize(AdminAcl::RESOURCE_NESTS)) {
|
||||
return $this->null();
|
||||
}
|
||||
|
||||
$model->loadMissing('nest');
|
||||
|
||||
return $this->item($model->getRelation('nest'), $this->makeTransformer(NestTransformer::class), Nest::RESOURCE_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Include the Servers relationship for the given Egg in the transformation.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Transformer\InvalidTransformerLevelException
|
||||
*/
|
||||
public function includeServers(Egg $model): Collection|NullResource
|
||||
{
|
||||
if (!$this->authorize(AdminAcl::RESOURCE_SERVERS)) {
|
||||
return $this->null();
|
||||
}
|
||||
|
||||
$model->loadMissing('servers');
|
||||
|
||||
return $this->collection($model->getRelation('servers'), $this->makeTransformer(ServerTransformer::class), Server::RESOURCE_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Include more detailed information about the configuration if this Egg is
|
||||
* extending another.
|
||||
|
@ -121,18 +81,27 @@ class EggTransformer extends BaseTransformer
|
|||
return $this->null();
|
||||
}
|
||||
|
||||
$model->loadMissing('configFrom');
|
||||
|
||||
return $this->item($model, function (Egg $model) {
|
||||
return [
|
||||
'files' => json_decode($model->inherit_config_files),
|
||||
'startup' => json_decode($model->inherit_config_startup),
|
||||
'stop' => $model->inherit_config_stop,
|
||||
'logs' => json_decode($model->inherit_config_logs),
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Include the Nest relationship for the given Egg in the transformation.
|
||||
*/
|
||||
public function includeNest(Egg $model): Item|NullResource
|
||||
{
|
||||
if (!$this->authorize(AdminAcl::RESOURCE_NESTS)) {
|
||||
return $this->null();
|
||||
}
|
||||
|
||||
return $this->item($model->nest, new NestTransformer());
|
||||
}
|
||||
|
||||
/**
|
||||
* Include more detailed information about the script configuration if the
|
||||
* Egg is extending another.
|
||||
|
@ -143,8 +112,6 @@ class EggTransformer extends BaseTransformer
|
|||
return $this->null();
|
||||
}
|
||||
|
||||
$model->loadMissing('scriptFrom');
|
||||
|
||||
return $this->item($model, function (Egg $model) {
|
||||
return [
|
||||
'privileged' => $model->script_is_privileged,
|
||||
|
@ -155,10 +122,20 @@ class EggTransformer extends BaseTransformer
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Include the Servers relationship for the given Egg in the transformation.
|
||||
*/
|
||||
public function includeServers(Egg $model): Collection|NullResource
|
||||
{
|
||||
if (!$this->authorize(AdminAcl::RESOURCE_SERVERS)) {
|
||||
return $this->null();
|
||||
}
|
||||
|
||||
return $this->collection($model->servers, new ServerTransformer());
|
||||
}
|
||||
|
||||
/**
|
||||
* Include the variables that are defined for this Egg.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Transformer\InvalidTransformerLevelException
|
||||
*/
|
||||
public function includeVariables(Egg $model): Collection|NullResource
|
||||
{
|
||||
|
@ -168,10 +145,6 @@ class EggTransformer extends BaseTransformer
|
|||
|
||||
$model->loadMissing('variables');
|
||||
|
||||
return $this->collection(
|
||||
$model->getRelation('variables'),
|
||||
$this->makeTransformer(EggVariableTransformer::class),
|
||||
EggVariable::RESOURCE_NAME
|
||||
);
|
||||
return $this->collection($model->variables, new EggVariableTransformer());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,8 +4,9 @@ namespace Pterodactyl\Transformers\Api\Application;
|
|||
|
||||
use Pterodactyl\Models\Egg;
|
||||
use Pterodactyl\Models\EggVariable;
|
||||
use Pterodactyl\Transformers\Api\Transformer;
|
||||
|
||||
class EggVariableTransformer extends BaseTransformer
|
||||
class EggVariableTransformer extends Transformer
|
||||
{
|
||||
/**
|
||||
* Return the resource name for the JSONAPI output.
|
||||
|
@ -15,7 +16,10 @@ class EggVariableTransformer extends BaseTransformer
|
|||
return Egg::RESOURCE_NAME;
|
||||
}
|
||||
|
||||
public function transform(EggVariable $model)
|
||||
/**
|
||||
* Transform egg variable into a representation for the application API.
|
||||
*/
|
||||
public function transform(EggVariable $model): array
|
||||
{
|
||||
return $model->toArray();
|
||||
}
|
||||
|
|
|
@ -6,8 +6,9 @@ use Pterodactyl\Models\Location;
|
|||
use League\Fractal\Resource\Collection;
|
||||
use League\Fractal\Resource\NullResource;
|
||||
use Pterodactyl\Services\Acl\Api\AdminAcl;
|
||||
use Pterodactyl\Transformers\Api\Transformer;
|
||||
|
||||
class LocationTransformer extends BaseTransformer
|
||||
class LocationTransformer extends Transformer
|
||||
{
|
||||
/**
|
||||
* List of resources that can be included.
|
||||
|
@ -25,37 +26,19 @@ class LocationTransformer extends BaseTransformer
|
|||
/**
|
||||
* Return a generic transformed location array.
|
||||
*/
|
||||
public function transform(Location $location): array
|
||||
public function transform(Location $model): array
|
||||
{
|
||||
return [
|
||||
'id' => $location->id,
|
||||
'short' => $location->short,
|
||||
'long' => $location->long,
|
||||
$location->getUpdatedAtColumn() => $this->formatTimestamp($location->updated_at),
|
||||
$location->getCreatedAtColumn() => $this->formatTimestamp($location->created_at),
|
||||
'id' => $model->id,
|
||||
'short' => $model->short,
|
||||
'long' => $model->long,
|
||||
'created_at' => self::formatTimestamp($model->created_at),
|
||||
'updated_at' => self::formatTimestamp($model->updated_at),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the nodes associated with this location.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Transformer\InvalidTransformerLevelException
|
||||
*/
|
||||
public function includeServers(Location $location): Collection|NullResource
|
||||
{
|
||||
if (!$this->authorize(AdminAcl::RESOURCE_SERVERS)) {
|
||||
return $this->null();
|
||||
}
|
||||
|
||||
$location->loadMissing('servers');
|
||||
|
||||
return $this->collection($location->getRelation('servers'), $this->makeTransformer(ServerTransformer::class), 'server');
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the nodes associated with this location.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Transformer\InvalidTransformerLevelException
|
||||
*/
|
||||
public function includeNodes(Location $location): Collection|NullResource
|
||||
{
|
||||
|
@ -63,8 +46,18 @@ class LocationTransformer extends BaseTransformer
|
|||
return $this->null();
|
||||
}
|
||||
|
||||
$location->loadMissing('nodes');
|
||||
return $this->collection($location->nodes, new NodeTransformer());
|
||||
}
|
||||
|
||||
return $this->collection($location->getRelation('nodes'), $this->makeTransformer(NodeTransformer::class), 'node');
|
||||
/**
|
||||
* Return the nodes associated with this location.
|
||||
*/
|
||||
public function includeServers(Location $location): Collection|NullResource
|
||||
{
|
||||
if (!$this->authorize(AdminAcl::RESOURCE_SERVERS)) {
|
||||
return $this->null();
|
||||
}
|
||||
|
||||
return $this->collection($location->servers, new ServerTransformer());
|
||||
}
|
||||
}
|
||||
|
|
75
app/Transformers/Api/Application/MountTransformer.php
Normal file
75
app/Transformers/Api/Application/MountTransformer.php
Normal file
|
@ -0,0 +1,75 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Transformers\Api\Application;
|
||||
|
||||
use Pterodactyl\Models\Mount;
|
||||
use League\Fractal\Resource\Collection;
|
||||
use League\Fractal\Resource\NullResource;
|
||||
use Pterodactyl\Services\Acl\Api\AdminAcl;
|
||||
use Pterodactyl\Transformers\Api\Transformer;
|
||||
|
||||
class MountTransformer extends Transformer
|
||||
{
|
||||
/**
|
||||
* List of resources that can be included.
|
||||
*/
|
||||
protected array $availableIncludes = ['eggs', 'nodes', 'servers'];
|
||||
|
||||
/**
|
||||
* Return the resource name for the JSONAPI output.
|
||||
*/
|
||||
public function getResourceName(): string
|
||||
{
|
||||
return Mount::RESOURCE_NAME;
|
||||
}
|
||||
|
||||
public function transform(Mount $model): array
|
||||
{
|
||||
return [
|
||||
'id' => $model->id,
|
||||
'uuid' => $model->uuid,
|
||||
'name' => $model->name,
|
||||
'description' => $model->description,
|
||||
'source' => $model->source,
|
||||
'target' => $model->target,
|
||||
'read_only' => $model->read_only,
|
||||
'user_mountable' => $model->user_mountable,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the eggs associated with this mount.
|
||||
*/
|
||||
public function includeEggs(Mount $mount): Collection|NullResource
|
||||
{
|
||||
if (!$this->authorize(AdminAcl::RESOURCE_EGGS)) {
|
||||
return $this->null();
|
||||
}
|
||||
|
||||
return $this->collection($mount->eggs, new EggTransformer());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the nodes associated with this mount.
|
||||
*/
|
||||
public function includeNodes(Mount $mount): Collection|NullResource
|
||||
{
|
||||
if (!$this->authorize(AdminAcl::RESOURCE_NODES)) {
|
||||
return $this->null();
|
||||
}
|
||||
|
||||
return $this->collection($mount->nodes, new NodeTransformer());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the servers associated with this mount.
|
||||
*/
|
||||
public function includeServers(Mount $mount): Collection|NullResource
|
||||
{
|
||||
if (!$this->authorize(AdminAcl::RESOURCE_SERVERS)) {
|
||||
return $this->null();
|
||||
}
|
||||
|
||||
return $this->collection($mount->servers, new ServerTransformer());
|
||||
}
|
||||
}
|
|
@ -2,21 +2,18 @@
|
|||
|
||||
namespace Pterodactyl\Transformers\Api\Application;
|
||||
|
||||
use Pterodactyl\Models\Egg;
|
||||
use Pterodactyl\Models\Nest;
|
||||
use Pterodactyl\Models\Server;
|
||||
use League\Fractal\Resource\Collection;
|
||||
use League\Fractal\Resource\NullResource;
|
||||
use Pterodactyl\Services\Acl\Api\AdminAcl;
|
||||
use Pterodactyl\Transformers\Api\Transformer;
|
||||
|
||||
class NestTransformer extends BaseTransformer
|
||||
class NestTransformer extends Transformer
|
||||
{
|
||||
/**
|
||||
* Relationships that can be loaded onto this transformation.
|
||||
*/
|
||||
protected array $availableIncludes = [
|
||||
'eggs', 'servers',
|
||||
];
|
||||
protected array $availableIncludes = ['eggs', 'servers'];
|
||||
|
||||
/**
|
||||
* Return the resource name for the JSONAPI output.
|
||||
|
@ -34,16 +31,14 @@ class NestTransformer extends BaseTransformer
|
|||
{
|
||||
$response = $model->toArray();
|
||||
|
||||
$response[$model->getUpdatedAtColumn()] = $this->formatTimestamp($model->updated_at);
|
||||
$response[$model->getCreatedAtColumn()] = $this->formatTimestamp($model->created_at);
|
||||
$response['created_at'] = self::formatTimestamp($model->created_at);
|
||||
$response['updated_at'] = self::formatTimestamp($model->updated_at);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Include the Eggs relationship on the given Nest model transformation.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Transformer\InvalidTransformerLevelException
|
||||
*/
|
||||
public function includeEggs(Nest $model): Collection|NullResource
|
||||
{
|
||||
|
@ -51,15 +46,11 @@ class NestTransformer extends BaseTransformer
|
|||
return $this->null();
|
||||
}
|
||||
|
||||
$model->loadMissing('eggs');
|
||||
|
||||
return $this->collection($model->getRelation('eggs'), $this->makeTransformer(EggTransformer::class), Egg::RESOURCE_NAME);
|
||||
return $this->collection($model->eggs, new EggTransformer());
|
||||
}
|
||||
|
||||
/**
|
||||
* Include the servers relationship on the given Nest model.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Transformer\InvalidTransformerLevelException
|
||||
*/
|
||||
public function includeServers(Nest $model): Collection|NullResource
|
||||
{
|
||||
|
@ -67,8 +58,6 @@ class NestTransformer extends BaseTransformer
|
|||
return $this->null();
|
||||
}
|
||||
|
||||
$model->loadMissing('servers');
|
||||
|
||||
return $this->collection($model->getRelation('servers'), $this->makeTransformer(ServerTransformer::class), Server::RESOURCE_NAME);
|
||||
return $this->collection($model->servers, new ServerTransformer());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,8 +7,9 @@ use League\Fractal\Resource\Item;
|
|||
use League\Fractal\Resource\Collection;
|
||||
use League\Fractal\Resource\NullResource;
|
||||
use Pterodactyl\Services\Acl\Api\AdminAcl;
|
||||
use Pterodactyl\Transformers\Api\Transformer;
|
||||
|
||||
class NodeTransformer extends BaseTransformer
|
||||
class NodeTransformer extends Transformer
|
||||
{
|
||||
/**
|
||||
* List of resources that can be included.
|
||||
|
@ -27,20 +28,14 @@ class NodeTransformer extends BaseTransformer
|
|||
* Return a node transformed into a format that can be consumed by the
|
||||
* external administrative API.
|
||||
*/
|
||||
public function transform(Node $node): array
|
||||
public function transform(Node $model): array
|
||||
{
|
||||
$response = collect($node->toArray())->mapWithKeys(function ($value, $key) {
|
||||
// I messed up early in 2016 when I named this column as poorly
|
||||
// as I did. This is the tragic result of my mistakes.
|
||||
$key = ($key === 'daemonSFTP') ? 'daemonSftp' : $key;
|
||||
$response = $model->toArray();
|
||||
|
||||
return [snake_case($key) => $value];
|
||||
})->toArray();
|
||||
$response['created_at'] = self::formatTimestamp($model->created_at);
|
||||
$response['updated_at'] = self::formatTimestamp($model->updated_at);
|
||||
|
||||
$response[$node->getUpdatedAtColumn()] = $this->formatTimestamp($node->updated_at);
|
||||
$response[$node->getCreatedAtColumn()] = $this->formatTimestamp($node->created_at);
|
||||
|
||||
$resources = $node->servers()->select(['memory', 'disk'])->get();
|
||||
$resources = $model->servers()->select(['memory', 'disk'])->get();
|
||||
|
||||
$response['allocated_resources'] = [
|
||||
'memory' => $resources->sum('memory'),
|
||||
|
@ -51,9 +46,7 @@ class NodeTransformer extends BaseTransformer
|
|||
}
|
||||
|
||||
/**
|
||||
* Return the nodes associated with this location.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Transformer\InvalidTransformerLevelException
|
||||
* Return the allocations associated with this node.
|
||||
*/
|
||||
public function includeAllocations(Node $node): Collection|NullResource
|
||||
{
|
||||
|
@ -61,19 +54,11 @@ class NodeTransformer extends BaseTransformer
|
|||
return $this->null();
|
||||
}
|
||||
|
||||
$node->loadMissing('allocations');
|
||||
|
||||
return $this->collection(
|
||||
$node->getRelation('allocations'),
|
||||
$this->makeTransformer(AllocationTransformer::class),
|
||||
'allocation'
|
||||
);
|
||||
return $this->collection($node->allocations, new AllocationTransformer());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the nodes associated with this location.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Transformer\InvalidTransformerLevelException
|
||||
* Return the location associated with this node.
|
||||
*/
|
||||
public function includeLocation(Node $node): Item|NullResource
|
||||
{
|
||||
|
@ -81,19 +66,11 @@ class NodeTransformer extends BaseTransformer
|
|||
return $this->null();
|
||||
}
|
||||
|
||||
$node->loadMissing('location');
|
||||
|
||||
return $this->item(
|
||||
$node->getRelation('location'),
|
||||
$this->makeTransformer(LocationTransformer::class),
|
||||
'location'
|
||||
);
|
||||
return $this->item($node->location, new LocationTransformer());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the nodes associated with this location.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Transformer\InvalidTransformerLevelException
|
||||
* Return the servers associated with this node.
|
||||
*/
|
||||
public function includeServers(Node $node): Collection|NullResource
|
||||
{
|
||||
|
@ -101,12 +78,6 @@ class NodeTransformer extends BaseTransformer
|
|||
return $this->null();
|
||||
}
|
||||
|
||||
$node->loadMissing('servers');
|
||||
|
||||
return $this->collection(
|
||||
$node->getRelation('servers'),
|
||||
$this->makeTransformer(ServerTransformer::class),
|
||||
'server'
|
||||
);
|
||||
return $this->collection($node->servers, new ServerTransformer());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,14 +4,14 @@ namespace Pterodactyl\Transformers\Api\Application;
|
|||
|
||||
use Pterodactyl\Models\Database;
|
||||
use League\Fractal\Resource\Item;
|
||||
use Pterodactyl\Models\DatabaseHost;
|
||||
use League\Fractal\Resource\NullResource;
|
||||
use Pterodactyl\Services\Acl\Api\AdminAcl;
|
||||
use Pterodactyl\Transformers\Api\Transformer;
|
||||
use Illuminate\Contracts\Encryption\Encrypter;
|
||||
|
||||
class ServerDatabaseTransformer extends BaseTransformer
|
||||
class ServerDatabaseTransformer extends Transformer
|
||||
{
|
||||
protected array $availableIncludes = ['password', 'host'];
|
||||
protected array $availableIncludes = ['host', 'password'];
|
||||
|
||||
private Encrypter $encrypter;
|
||||
|
||||
|
@ -38,17 +38,29 @@ class ServerDatabaseTransformer extends BaseTransformer
|
|||
{
|
||||
return [
|
||||
'id' => $model->id,
|
||||
'server' => $model->server_id,
|
||||
'host' => $model->database_host_id,
|
||||
'database' => $model->database,
|
||||
'database_host_id' => $model->database_host_id,
|
||||
'server_id' => $model->server_id,
|
||||
'name' => $model->database,
|
||||
'username' => $model->username,
|
||||
'remote' => $model->remote,
|
||||
'max_connections' => $model->max_connections,
|
||||
'created_at' => $model->created_at->toAtomString(),
|
||||
'updated_at' => $model->updated_at->toAtomString(),
|
||||
'created_at' => self::formatTimestamp($model->created_at),
|
||||
'updated_at' => self::formatTimestamp($model->updated_at),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the database host relationship for this server database.
|
||||
*/
|
||||
public function includeHost(Database $model): Item|NullResource
|
||||
{
|
||||
if (!$this->authorize(AdminAcl::RESOURCE_DATABASE_HOSTS)) {
|
||||
return $this->null();
|
||||
}
|
||||
|
||||
return $this->item($model->host, new DatabaseHostTransformer());
|
||||
}
|
||||
|
||||
/**
|
||||
* Include the database password in the request.
|
||||
*/
|
||||
|
@ -60,24 +72,4 @@ class ServerDatabaseTransformer extends BaseTransformer
|
|||
];
|
||||
}, 'database_password');
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the database host relationship for this server database.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Transformer\InvalidTransformerLevelException
|
||||
*/
|
||||
public function includeHost(Database $model): Item|NullResource
|
||||
{
|
||||
if (!$this->authorize(AdminAcl::RESOURCE_DATABASE_HOSTS)) {
|
||||
return $this->null();
|
||||
}
|
||||
|
||||
$model->loadMissing('host');
|
||||
|
||||
return $this->item(
|
||||
$model->getRelation('host'),
|
||||
$this->makeTransformer(DatabaseHostTransformer::class),
|
||||
DatabaseHost::RESOURCE_NAME
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,9 +7,10 @@ use League\Fractal\Resource\Item;
|
|||
use League\Fractal\Resource\Collection;
|
||||
use League\Fractal\Resource\NullResource;
|
||||
use Pterodactyl\Services\Acl\Api\AdminAcl;
|
||||
use Pterodactyl\Transformers\Api\Transformer;
|
||||
use Pterodactyl\Services\Servers\EnvironmentService;
|
||||
|
||||
class ServerTransformer extends BaseTransformer
|
||||
class ServerTransformer extends Transformer
|
||||
{
|
||||
private EnvironmentService $environmentService;
|
||||
|
||||
|
@ -48,53 +49,47 @@ class ServerTransformer extends BaseTransformer
|
|||
/**
|
||||
* Return a generic transformed server array.
|
||||
*/
|
||||
public function transform(Server $server): array
|
||||
public function transform(Server $model): array
|
||||
{
|
||||
return [
|
||||
'id' => $server->getKey(),
|
||||
'external_id' => $server->external_id,
|
||||
'uuid' => $server->uuid,
|
||||
'identifier' => $server->uuidShort,
|
||||
'name' => $server->name,
|
||||
'description' => $server->description,
|
||||
'status' => $server->status,
|
||||
// This field is deprecated, please use "status".
|
||||
'suspended' => $server->isSuspended(),
|
||||
'id' => $model->getKey(),
|
||||
'external_id' => $model->external_id,
|
||||
'uuid' => $model->uuid,
|
||||
'identifier' => $model->uuidShort,
|
||||
'name' => $model->name,
|
||||
'description' => $model->description,
|
||||
'status' => $model->status,
|
||||
'limits' => [
|
||||
'memory' => $server->memory,
|
||||
'swap' => $server->swap,
|
||||
'disk' => $server->disk,
|
||||
'io' => $server->io,
|
||||
'cpu' => $server->cpu,
|
||||
'threads' => $server->threads,
|
||||
'oom_disabled' => $server->oom_disabled,
|
||||
'cpu' => $model->cpu,
|
||||
'disk' => $model->disk,
|
||||
'io' => $model->io,
|
||||
'memory' => $model->memory,
|
||||
'oom_killer' => $model->oom_killer,
|
||||
'swap' => $model->swap,
|
||||
'threads' => $model->threads,
|
||||
],
|
||||
'feature_limits' => [
|
||||
'databases' => $server->database_limit,
|
||||
'allocations' => $server->allocation_limit,
|
||||
'backups' => $server->backup_limit,
|
||||
'allocations' => $model->allocation_limit,
|
||||
'backups' => $model->backup_limit,
|
||||
'databases' => $model->database_limit,
|
||||
],
|
||||
'user' => $server->owner_id,
|
||||
'node' => $server->node_id,
|
||||
'allocation' => $server->allocation_id,
|
||||
'nest' => $server->nest_id,
|
||||
'egg' => $server->egg_id,
|
||||
'owner_id' => $model->owner_id,
|
||||
'node_id' => $model->node_id,
|
||||
'allocation_id' => $model->allocation_id,
|
||||
'nest_id' => $model->nest_id,
|
||||
'egg_id' => $model->egg_id,
|
||||
'container' => [
|
||||
'startup_command' => $server->startup,
|
||||
'image' => $server->image,
|
||||
// This field is deprecated, please use "status".
|
||||
'installed' => $server->isInstalled() ? 1 : 0,
|
||||
'environment' => $this->environmentService->handle($server),
|
||||
'startup' => $model->startup,
|
||||
'image' => $model->image,
|
||||
'environment' => $this->environmentService->handle($model),
|
||||
],
|
||||
$server->getUpdatedAtColumn() => $this->formatTimestamp($server->updated_at),
|
||||
$server->getCreatedAtColumn() => $this->formatTimestamp($server->created_at),
|
||||
'created_at' => self::formatTimestamp($model->created_at),
|
||||
'updated_at' => self::formatTimestamp($model->updated_at),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a generic array of allocations for this server.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Transformer\InvalidTransformerLevelException
|
||||
*/
|
||||
public function includeAllocations(Server $server): Collection|NullResource
|
||||
{
|
||||
|
@ -102,15 +97,11 @@ class ServerTransformer extends BaseTransformer
|
|||
return $this->null();
|
||||
}
|
||||
|
||||
$server->loadMissing('allocations');
|
||||
|
||||
return $this->collection($server->getRelation('allocations'), $this->makeTransformer(AllocationTransformer::class), 'allocation');
|
||||
return $this->collection($server->allocations, new AllocationTransformer());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a generic array of data about subusers for this server.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Transformer\InvalidTransformerLevelException
|
||||
*/
|
||||
public function includeSubusers(Server $server): Collection|NullResource
|
||||
{
|
||||
|
@ -118,15 +109,11 @@ class ServerTransformer extends BaseTransformer
|
|||
return $this->null();
|
||||
}
|
||||
|
||||
$server->loadMissing('subusers');
|
||||
|
||||
return $this->collection($server->getRelation('subusers'), $this->makeTransformer(SubuserTransformer::class), 'subuser');
|
||||
return $this->collection($server->subusers, new SubuserTransformer());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a generic array of data about subusers for this server.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Transformer\InvalidTransformerLevelException
|
||||
*/
|
||||
public function includeUser(Server $server): Item|NullResource
|
||||
{
|
||||
|
@ -134,15 +121,11 @@ class ServerTransformer extends BaseTransformer
|
|||
return $this->null();
|
||||
}
|
||||
|
||||
$server->loadMissing('user');
|
||||
|
||||
return $this->item($server->getRelation('user'), $this->makeTransformer(UserTransformer::class), 'user');
|
||||
return $this->item($server->user, new UserTransformer());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a generic array with nest information for this server.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Transformer\InvalidTransformerLevelException
|
||||
*/
|
||||
public function includeNest(Server $server): Item|NullResource
|
||||
{
|
||||
|
@ -150,15 +133,11 @@ class ServerTransformer extends BaseTransformer
|
|||
return $this->null();
|
||||
}
|
||||
|
||||
$server->loadMissing('nest');
|
||||
|
||||
return $this->item($server->getRelation('nest'), $this->makeTransformer(NestTransformer::class), 'nest');
|
||||
return $this->item($server->nest, new NestTransformer());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a generic array with egg information for this server.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Transformer\InvalidTransformerLevelException
|
||||
*/
|
||||
public function includeEgg(Server $server): Item|NullResource
|
||||
{
|
||||
|
@ -166,15 +145,11 @@ class ServerTransformer extends BaseTransformer
|
|||
return $this->null();
|
||||
}
|
||||
|
||||
$server->loadMissing('egg');
|
||||
|
||||
return $this->item($server->getRelation('egg'), $this->makeTransformer(EggTransformer::class), 'egg');
|
||||
return $this->item($server->egg, new EggTransformer());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a generic array of data about subusers for this server.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Transformer\InvalidTransformerLevelException
|
||||
*/
|
||||
public function includeVariables(Server $server): Collection|NullResource
|
||||
{
|
||||
|
@ -182,15 +157,11 @@ class ServerTransformer extends BaseTransformer
|
|||
return $this->null();
|
||||
}
|
||||
|
||||
$server->loadMissing('variables');
|
||||
|
||||
return $this->collection($server->getRelation('variables'), $this->makeTransformer(ServerVariableTransformer::class), 'server_variable');
|
||||
return $this->collection($server->variables, new ServerVariableTransformer());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a generic array with location information for this server.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Transformer\InvalidTransformerLevelException
|
||||
*/
|
||||
public function includeLocation(Server $server): Item|NullResource
|
||||
{
|
||||
|
@ -198,15 +169,11 @@ class ServerTransformer extends BaseTransformer
|
|||
return $this->null();
|
||||
}
|
||||
|
||||
$server->loadMissing('location');
|
||||
|
||||
return $this->item($server->getRelation('location'), $this->makeTransformer(LocationTransformer::class), 'location');
|
||||
return $this->item($server->location, new LocationTransformer());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a generic array with node information for this server.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Transformer\InvalidTransformerLevelException
|
||||
*/
|
||||
public function includeNode(Server $server): Item|NullResource
|
||||
{
|
||||
|
@ -214,15 +181,11 @@ class ServerTransformer extends BaseTransformer
|
|||
return $this->null();
|
||||
}
|
||||
|
||||
$server->loadMissing('node');
|
||||
|
||||
return $this->item($server->getRelation('node'), $this->makeTransformer(NodeTransformer::class), 'node');
|
||||
return $this->item($server->node, new NodeTransformer());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a generic array with database information for this server.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Transformer\InvalidTransformerLevelException
|
||||
*/
|
||||
public function includeDatabases(Server $server): Collection|NullResource
|
||||
{
|
||||
|
@ -230,8 +193,6 @@ class ServerTransformer extends BaseTransformer
|
|||
return $this->null();
|
||||
}
|
||||
|
||||
$server->loadMissing('databases');
|
||||
|
||||
return $this->collection($server->getRelation('databases'), $this->makeTransformer(ServerDatabaseTransformer::class), 'databases');
|
||||
return $this->collection($server->databases, new ServerDatabaseTransformer());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,18 +2,12 @@
|
|||
|
||||
namespace Pterodactyl\Transformers\Api\Application;
|
||||
|
||||
use League\Fractal\Resource\Item;
|
||||
use Pterodactyl\Models\EggVariable;
|
||||
use League\Fractal\Resource\NullResource;
|
||||
use Pterodactyl\Services\Acl\Api\AdminAcl;
|
||||
use Pterodactyl\Models\ServerVariable;
|
||||
use Pterodactyl\Transformers\Api\Transformer;
|
||||
|
||||
class ServerVariableTransformer extends BaseTransformer
|
||||
class ServerVariableTransformer extends Transformer
|
||||
{
|
||||
/**
|
||||
* List of resources that can be included.
|
||||
*/
|
||||
protected array $availableIncludes = ['parent'];
|
||||
|
||||
/**
|
||||
* Return the resource name for the JSONAPI output.
|
||||
*/
|
||||
|
@ -25,24 +19,8 @@ class ServerVariableTransformer extends BaseTransformer
|
|||
/**
|
||||
* Return a generic transformed server variable array.
|
||||
*/
|
||||
public function transform(EggVariable $variable): array
|
||||
public function transform(EggVariable $model): array
|
||||
{
|
||||
return $variable->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the parent service variable data.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Transformer\InvalidTransformerLevelException
|
||||
*/
|
||||
public function includeParent(EggVariable $variable): Item|NullResource
|
||||
{
|
||||
if (!$this->authorize(AdminAcl::RESOURCE_EGGS)) {
|
||||
return $this->null();
|
||||
}
|
||||
|
||||
$variable->loadMissing('variable');
|
||||
|
||||
return $this->item($variable->getRelation('variable'), $this->makeTransformer(EggVariableTransformer::class), 'variable');
|
||||
return $model->toArray();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,13 +6,14 @@ use Pterodactyl\Models\Subuser;
|
|||
use League\Fractal\Resource\Item;
|
||||
use League\Fractal\Resource\NullResource;
|
||||
use Pterodactyl\Services\Acl\Api\AdminAcl;
|
||||
use Pterodactyl\Transformers\Api\Transformer;
|
||||
|
||||
class SubuserTransformer extends BaseTransformer
|
||||
class SubuserTransformer extends Transformer
|
||||
{
|
||||
/**
|
||||
* List of resources that can be included.
|
||||
*/
|
||||
protected array $availableIncludes = ['user', 'server'];
|
||||
protected array $availableIncludes = ['server', 'user'];
|
||||
|
||||
/**
|
||||
* Return the resource name for the JSONAPI output.
|
||||
|
@ -25,38 +26,20 @@ class SubuserTransformer extends BaseTransformer
|
|||
/**
|
||||
* Return a transformed Subuser model that can be consumed by external services.
|
||||
*/
|
||||
public function transform(Subuser $subuser): array
|
||||
public function transform(Subuser $model): array
|
||||
{
|
||||
return [
|
||||
'id' => $subuser->id,
|
||||
'user_id' => $subuser->user_id,
|
||||
'server_id' => $subuser->server_id,
|
||||
'permissions' => $subuser->permissions,
|
||||
'created_at' => $this->formatTimestamp($subuser->created_at),
|
||||
'updated_at' => $this->formatTimestamp($subuser->updated_at),
|
||||
'id' => $model->id,
|
||||
'user_id' => $model->user_id,
|
||||
'server_id' => $model->server_id,
|
||||
'permissions' => $model->permissions,
|
||||
'created_at' => self::formatTimestamp($model->created_at),
|
||||
'updated_at' => self::formatTimestamp($model->updated_at),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a generic item of user for this subuser.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Transformer\InvalidTransformerLevelException
|
||||
*/
|
||||
public function includeUser(Subuser $subuser): Item|NullResource
|
||||
{
|
||||
if (!$this->authorize(AdminAcl::RESOURCE_USERS)) {
|
||||
return $this->null();
|
||||
}
|
||||
|
||||
$subuser->loadMissing('user');
|
||||
|
||||
return $this->item($subuser->getRelation('user'), $this->makeTransformer(UserTransformer::class), 'user');
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a generic item of server for this subuser.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Transformer\InvalidTransformerLevelException
|
||||
*/
|
||||
public function includeServer(Subuser $subuser): Item|NullResource
|
||||
{
|
||||
|
@ -64,8 +47,18 @@ class SubuserTransformer extends BaseTransformer
|
|||
return $this->null();
|
||||
}
|
||||
|
||||
$subuser->loadMissing('server');
|
||||
return $this->item($subuser->server, new ServerTransformer());
|
||||
}
|
||||
|
||||
return $this->item($subuser->getRelation('server'), $this->makeTransformer(ServerTransformer::class), 'server');
|
||||
/**
|
||||
* Return a generic item of user for this subuser.
|
||||
*/
|
||||
public function includeUser(Subuser $subuser): Item|NullResource
|
||||
{
|
||||
if (!$this->authorize(AdminAcl::RESOURCE_USERS)) {
|
||||
return $this->null();
|
||||
}
|
||||
|
||||
return $this->item($subuser->user, new UserTransformer());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,8 +6,9 @@ use Pterodactyl\Models\User;
|
|||
use League\Fractal\Resource\Collection;
|
||||
use League\Fractal\Resource\NullResource;
|
||||
use Pterodactyl\Services\Acl\Api\AdminAcl;
|
||||
use Pterodactyl\Transformers\Api\Transformer;
|
||||
|
||||
class UserTransformer extends BaseTransformer
|
||||
class UserTransformer extends Transformer
|
||||
{
|
||||
/**
|
||||
* List of resources that can be included.
|
||||
|
@ -25,28 +26,27 @@ class UserTransformer extends BaseTransformer
|
|||
/**
|
||||
* Return a transformed User model that can be consumed by external services.
|
||||
*/
|
||||
public function transform(User $user): array
|
||||
public function transform(User $model): array
|
||||
{
|
||||
return [
|
||||
'id' => $user->id,
|
||||
'external_id' => $user->external_id,
|
||||
'uuid' => $user->uuid,
|
||||
'username' => $user->username,
|
||||
'email' => $user->email,
|
||||
'first_name' => $user->name_first,
|
||||
'last_name' => $user->name_last,
|
||||
'language' => $user->language,
|
||||
'root_admin' => (bool) $user->root_admin,
|
||||
'2fa' => (bool) $user->use_totp,
|
||||
'created_at' => $this->formatTimestamp($user->created_at),
|
||||
'updated_at' => $this->formatTimestamp($user->updated_at),
|
||||
'id' => $model->id,
|
||||
'external_id' => $model->external_id,
|
||||
'uuid' => $model->uuid,
|
||||
'username' => $model->username,
|
||||
'email' => $model->email,
|
||||
'language' => $model->language,
|
||||
'root_admin' => (bool) $model->root_admin,
|
||||
'2fa' => (bool) $model->use_totp,
|
||||
'avatar_url' => $model->avatar_url,
|
||||
'admin_role_id' => $model->admin_role_id,
|
||||
'role_name' => $model->admin_role_name,
|
||||
'created_at' => self::formatTimestamp($model->created_at),
|
||||
'updated_at' => self::formatTimestamp($model->updated_at),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the servers associated with this user.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Transformer\InvalidTransformerLevelException
|
||||
*/
|
||||
public function includeServers(User $user): Collection|NullResource
|
||||
{
|
||||
|
@ -54,8 +54,6 @@ class UserTransformer extends BaseTransformer
|
|||
return $this->null();
|
||||
}
|
||||
|
||||
$user->loadMissing('servers');
|
||||
|
||||
return $this->collection($user->getRelation('servers'), $this->makeTransformer(ServerTransformer::class), 'server');
|
||||
return $this->collection($user->servers, new ServerTransformer());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,8 +3,9 @@
|
|||
namespace Pterodactyl\Transformers\Api\Client;
|
||||
|
||||
use Pterodactyl\Models\User;
|
||||
use Pterodactyl\Transformers\Api\Transformer;
|
||||
|
||||
class AccountTransformer extends BaseClientTransformer
|
||||
class AccountTransformer extends Transformer
|
||||
{
|
||||
/**
|
||||
* Return the resource name for the JSONAPI output.
|
||||
|
@ -24,8 +25,6 @@ class AccountTransformer extends BaseClientTransformer
|
|||
'admin' => $model->root_admin,
|
||||
'username' => $model->username,
|
||||
'email' => $model->email,
|
||||
'first_name' => $model->name_first,
|
||||
'last_name' => $model->name_last,
|
||||
'language' => $model->language,
|
||||
];
|
||||
}
|
||||
|
|
|
@ -4,10 +4,13 @@ namespace Pterodactyl\Transformers\Api\Client;
|
|||
|
||||
use Illuminate\Support\Str;
|
||||
use Pterodactyl\Models\User;
|
||||
use League\Fractal\Resource\Item;
|
||||
use Pterodactyl\Models\ActivityLog;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use League\Fractal\Resource\NullResource;
|
||||
use Pterodactyl\Transformers\Api\Transformer;
|
||||
|
||||
class ActivityLogTransformer extends BaseClientTransformer
|
||||
class ActivityLogTransformer extends Transformer
|
||||
{
|
||||
protected array $availableIncludes = ['actor'];
|
||||
|
||||
|
@ -34,23 +37,23 @@ class ActivityLogTransformer extends BaseClientTransformer
|
|||
];
|
||||
}
|
||||
|
||||
public function includeActor(ActivityLog $model)
|
||||
public function includeActor(ActivityLog $model): Item|NullResource
|
||||
{
|
||||
if (!$model->actor instanceof User) {
|
||||
return $this->null();
|
||||
}
|
||||
|
||||
return $this->item($model->actor, $this->makeTransformer(UserTransformer::class), User::RESOURCE_NAME);
|
||||
return $this->item($model->actor, new UserTransformer());
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms any array values in the properties into a countable field for easier
|
||||
* use within the translation outputs.
|
||||
*/
|
||||
protected function properties(ActivityLog $model): array
|
||||
protected function properties(ActivityLog $model): object
|
||||
{
|
||||
if (!$model->properties || $model->properties->isEmpty()) {
|
||||
return [];
|
||||
return (object) [];
|
||||
}
|
||||
|
||||
$properties = $model->properties
|
||||
|
@ -76,7 +79,7 @@ class ActivityLogTransformer extends BaseClientTransformer
|
|||
$properties = $properties->merge(['count' => $properties->get($keys[0])])->except($keys[0]);
|
||||
}
|
||||
|
||||
return $properties->toArray();
|
||||
return (object) $properties->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -3,8 +3,9 @@
|
|||
namespace Pterodactyl\Transformers\Api\Client;
|
||||
|
||||
use Pterodactyl\Models\Allocation;
|
||||
use Pterodactyl\Transformers\Api\Transformer;
|
||||
|
||||
class AllocationTransformer extends BaseClientTransformer
|
||||
class AllocationTransformer extends Transformer
|
||||
{
|
||||
/**
|
||||
* Return the resource name for the JSONAPI output.
|
||||
|
|
|
@ -3,8 +3,9 @@
|
|||
namespace Pterodactyl\Transformers\Api\Client;
|
||||
|
||||
use Pterodactyl\Models\ApiKey;
|
||||
use Pterodactyl\Transformers\Api\Transformer;
|
||||
|
||||
class ApiKeyTransformer extends BaseClientTransformer
|
||||
class ApiKeyTransformer extends Transformer
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
|
|
@ -3,26 +3,27 @@
|
|||
namespace Pterodactyl\Transformers\Api\Client;
|
||||
|
||||
use Pterodactyl\Models\Backup;
|
||||
use Pterodactyl\Transformers\Api\Transformer;
|
||||
|
||||
class BackupTransformer extends BaseClientTransformer
|
||||
class BackupTransformer extends Transformer
|
||||
{
|
||||
public function getResourceName(): string
|
||||
{
|
||||
return Backup::RESOURCE_NAME;
|
||||
}
|
||||
|
||||
public function transform(Backup $backup): array
|
||||
public function transform(Backup $model): array
|
||||
{
|
||||
return [
|
||||
'uuid' => $backup->uuid,
|
||||
'is_successful' => $backup->is_successful,
|
||||
'is_locked' => $backup->is_locked,
|
||||
'name' => $backup->name,
|
||||
'ignored_files' => $backup->ignored_files,
|
||||
'checksum' => $backup->checksum,
|
||||
'bytes' => $backup->bytes,
|
||||
'created_at' => $backup->created_at->toAtomString(),
|
||||
'completed_at' => $backup->completed_at ? $backup->completed_at->toAtomString() : null,
|
||||
'uuid' => $model->uuid,
|
||||
'is_successful' => $model->is_successful,
|
||||
'is_locked' => $model->is_locked,
|
||||
'name' => $model->name,
|
||||
'ignored_files' => $model->ignored_files,
|
||||
'checksum' => $model->checksum,
|
||||
'bytes' => $model->bytes,
|
||||
'created_at' => self::formatTimestamp($model->created_at),
|
||||
'completed_at' => self::formatTimestamp($model->completed_at),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,43 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Transformers\Api\Client;
|
||||
|
||||
use Pterodactyl\Models\User;
|
||||
use Webmozart\Assert\Assert;
|
||||
use Pterodactyl\Models\Server;
|
||||
use Pterodactyl\Transformers\Api\Application\BaseTransformer as BaseApplicationTransformer;
|
||||
|
||||
abstract class BaseClientTransformer extends BaseApplicationTransformer
|
||||
{
|
||||
/**
|
||||
* Return the user model of the user requesting this transformation.
|
||||
*/
|
||||
public function getUser(): User
|
||||
{
|
||||
return $this->request->user();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the API key loaded onto the transformer has permission
|
||||
* to access a different resource. This is used when including other
|
||||
* models on a transformation request.
|
||||
*
|
||||
* @noinspection PhpParameterNameChangedDuringInheritanceInspection
|
||||
*/
|
||||
protected function authorize(string $ability, Server $server = null): bool
|
||||
{
|
||||
Assert::isInstanceOf($server, Server::class);
|
||||
|
||||
return $this->request->user()->can($ability, [$server]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function makeTransformer(string $abstract)
|
||||
{
|
||||
Assert::subclassOf($abstract, self::class);
|
||||
|
||||
return parent::makeTransformer($abstract);
|
||||
}
|
||||
}
|
|
@ -6,15 +6,15 @@ use Pterodactyl\Models\Database;
|
|||
use League\Fractal\Resource\Item;
|
||||
use Pterodactyl\Models\Permission;
|
||||
use League\Fractal\Resource\NullResource;
|
||||
use Pterodactyl\Transformers\Api\Transformer;
|
||||
use Illuminate\Contracts\Encryption\Encrypter;
|
||||
use Pterodactyl\Contracts\Extensions\HashidsInterface;
|
||||
|
||||
class DatabaseTransformer extends BaseClientTransformer
|
||||
class DatabaseTransformer extends Transformer
|
||||
{
|
||||
protected array $availableIncludes = ['password'];
|
||||
|
||||
private Encrypter $encrypter;
|
||||
|
||||
private HashidsInterface $hashids;
|
||||
|
||||
/**
|
||||
|
@ -38,8 +38,8 @@ class DatabaseTransformer extends BaseClientTransformer
|
|||
return [
|
||||
'id' => $this->hashids->encode($model->id),
|
||||
'host' => [
|
||||
'address' => $model->getRelation('host')->host,
|
||||
'port' => $model->getRelation('host')->port,
|
||||
'address' => $model->host->host,
|
||||
'port' => $model->host->port,
|
||||
],
|
||||
'name' => $model->database,
|
||||
'username' => $model->username,
|
||||
|
@ -53,7 +53,7 @@ class DatabaseTransformer extends BaseClientTransformer
|
|||
*/
|
||||
public function includePassword(Database $database): Item|NullResource
|
||||
{
|
||||
if (!$this->request->user()->can(Permission::ACTION_DATABASE_VIEW_PASSWORD, $database->server)) {
|
||||
if ($this->user()->cannot(Permission::ACTION_DATABASE_VIEW_PASSWORD, $database->server)) {
|
||||
return $this->null();
|
||||
}
|
||||
|
||||
|
|
|
@ -3,8 +3,9 @@
|
|||
namespace Pterodactyl\Transformers\Api\Client;
|
||||
|
||||
use Pterodactyl\Models\Egg;
|
||||
use Pterodactyl\Transformers\Api\Transformer;
|
||||
|
||||
class EggTransformer extends BaseClientTransformer
|
||||
class EggTransformer extends Transformer
|
||||
{
|
||||
/**
|
||||
* Return the resource name for the JSONAPI output.
|
||||
|
@ -14,11 +15,11 @@ class EggTransformer extends BaseClientTransformer
|
|||
return Egg::RESOURCE_NAME;
|
||||
}
|
||||
|
||||
public function transform(Egg $egg): array
|
||||
public function transform(Egg $model): array
|
||||
{
|
||||
return [
|
||||
'uuid' => $egg->uuid,
|
||||
'name' => $egg->name,
|
||||
'uuid' => $model->uuid,
|
||||
'name' => $model->name,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,33 +2,33 @@
|
|||
|
||||
namespace Pterodactyl\Transformers\Api\Client;
|
||||
|
||||
use BadMethodCallException;
|
||||
use Pterodactyl\Models\EggVariable;
|
||||
use Pterodactyl\Transformers\Api\Transformer;
|
||||
|
||||
class EggVariableTransformer extends BaseClientTransformer
|
||||
class EggVariableTransformer extends Transformer
|
||||
{
|
||||
public function getResourceName(): string
|
||||
{
|
||||
return EggVariable::RESOURCE_NAME;
|
||||
}
|
||||
|
||||
public function transform(EggVariable $variable): array
|
||||
public function transform(EggVariable $model): array
|
||||
{
|
||||
// This guards against someone incorrectly retrieving variables (haha, me) and then passing
|
||||
// them into the transformer and along to the user. Just throw an exception and break the entire
|
||||
// pathway since you should never be exposing these types of variables to a client.
|
||||
if (!$variable->user_viewable) {
|
||||
throw new BadMethodCallException('Cannot transform a hidden egg variable in a client transformer.');
|
||||
if (!$model->user_viewable) {
|
||||
throw new \BadMethodCallException('Cannot transform a hidden egg variable in a client transformer.');
|
||||
}
|
||||
|
||||
return [
|
||||
'name' => $variable->name,
|
||||
'description' => $variable->description,
|
||||
'env_variable' => $variable->env_variable,
|
||||
'default_value' => $variable->default_value,
|
||||
'server_value' => $variable->server_value,
|
||||
'is_editable' => $variable->user_editable,
|
||||
'rules' => $variable->rules,
|
||||
'name' => $model->name,
|
||||
'description' => $model->description,
|
||||
'env_variable' => $model->env_variable,
|
||||
'default_value' => $model->default_value,
|
||||
'server_value' => $model->server_value,
|
||||
'is_editable' => $model->user_editable,
|
||||
'rules' => $model->rules,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,29 +4,30 @@ namespace Pterodactyl\Transformers\Api\Client;
|
|||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Arr;
|
||||
use Pterodactyl\Transformers\Api\Transformer;
|
||||
|
||||
class FileObjectTransformer extends BaseClientTransformer
|
||||
class FileObjectTransformer extends Transformer
|
||||
{
|
||||
/**
|
||||
* Transform a file object response from the daemon into a standardized response.
|
||||
*/
|
||||
public function transform(array $item): array
|
||||
{
|
||||
return [
|
||||
'name' => Arr::get($item, 'name'),
|
||||
'mode' => Arr::get($item, 'mode'),
|
||||
'mode_bits' => Arr::get($item, 'mode_bits'),
|
||||
'size' => Arr::get($item, 'size'),
|
||||
'is_file' => Arr::get($item, 'file', true),
|
||||
'is_symlink' => Arr::get($item, 'symlink', false),
|
||||
'mimetype' => Arr::get($item, 'mime', 'application/octet-stream'),
|
||||
'created_at' => Carbon::parse(Arr::get($item, 'created', ''))->toAtomString(),
|
||||
'modified_at' => Carbon::parse(Arr::get($item, 'modified', ''))->toAtomString(),
|
||||
];
|
||||
}
|
||||
|
||||
public function getResourceName(): string
|
||||
{
|
||||
return 'file_object';
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform a file object response from the daemon into a standardized response.
|
||||
*/
|
||||
public function transform(array $model): array
|
||||
{
|
||||
return [
|
||||
'name' => Arr::get($model, 'name'),
|
||||
'mode' => Arr::get($model, 'mode'),
|
||||
'mode_bits' => Arr::get($model, 'mode_bits'),
|
||||
'size' => Arr::get($model, 'size'),
|
||||
'is_file' => Arr::get($model, 'file', true),
|
||||
'is_symlink' => Arr::get($model, 'symlink', false),
|
||||
'mimetype' => Arr::get($model, 'mime', 'application/octet-stream'),
|
||||
'created_at' => Carbon::parse(Arr::get($model, 'created', ''))->toAtomString(),
|
||||
'modified_at' => Carbon::parse(Arr::get($model, 'modified', ''))->toAtomString(),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
|
||||
namespace Pterodactyl\Transformers\Api\Client;
|
||||
|
||||
use Pterodactyl\Models\Task;
|
||||
use Pterodactyl\Models\Schedule;
|
||||
use League\Fractal\Resource\Collection;
|
||||
use Pterodactyl\Transformers\Api\Transformer;
|
||||
|
||||
class ScheduleTransformer extends BaseClientTransformer
|
||||
class ScheduleTransformer extends Transformer
|
||||
{
|
||||
protected array $availableIncludes = ['tasks'];
|
||||
|
||||
|
@ -38,24 +38,18 @@ class ScheduleTransformer extends BaseClientTransformer
|
|||
'is_active' => $model->is_active,
|
||||
'is_processing' => $model->is_processing,
|
||||
'only_when_online' => $model->only_when_online,
|
||||
'last_run_at' => $model->last_run_at?->toAtomString(),
|
||||
'next_run_at' => $model->next_run_at?->toAtomString(),
|
||||
'created_at' => $model->created_at->toAtomString(),
|
||||
'updated_at' => $model->updated_at->toAtomString(),
|
||||
'last_run_at' => self::formatTimestamp($model->last_run_at),
|
||||
'next_run_at' => self::formatTimestamp($model->next_run_at),
|
||||
'created_at' => self::formatTimestamp($model->created_at),
|
||||
'updated_at' => self::formatTimestamp($model->updated_at),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows attaching the tasks specific to the schedule in the response.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Transformer\InvalidTransformerLevelException
|
||||
*/
|
||||
public function includeTasks(Schedule $model): Collection
|
||||
{
|
||||
return $this->collection(
|
||||
$model->tasks,
|
||||
$this->makeTransformer(TaskTransformer::class),
|
||||
Task::RESOURCE_NAME
|
||||
);
|
||||
return $this->collection($model->tasks, new TaskTransformer());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,17 +4,16 @@ namespace Pterodactyl\Transformers\Api\Client;
|
|||
|
||||
use Pterodactyl\Models\Egg;
|
||||
use Pterodactyl\Models\Server;
|
||||
use Pterodactyl\Models\Subuser;
|
||||
use League\Fractal\Resource\Item;
|
||||
use Pterodactyl\Models\Allocation;
|
||||
use Pterodactyl\Models\Permission;
|
||||
use Illuminate\Container\Container;
|
||||
use Pterodactyl\Models\EggVariable;
|
||||
use League\Fractal\Resource\Collection;
|
||||
use League\Fractal\Resource\NullResource;
|
||||
use Pterodactyl\Transformers\Api\Transformer;
|
||||
use Pterodactyl\Services\Servers\StartupCommandService;
|
||||
|
||||
class ServerTransformer extends BaseClientTransformer
|
||||
class ServerTransformer extends Transformer
|
||||
{
|
||||
protected array $defaultIncludes = ['allocations', 'variables'];
|
||||
|
||||
|
@ -43,9 +42,10 @@ class ServerTransformer extends BaseClientTransformer
|
|||
'uuid' => $server->uuid,
|
||||
'name' => $server->name,
|
||||
'node' => $server->node->name,
|
||||
'is_node_under_maintenance' => $server->node->isUnderMaintenance(),
|
||||
'sftp_details' => [
|
||||
'ip' => $server->node->fqdn,
|
||||
'port' => $server->node->daemonSFTP,
|
||||
'port' => $server->node->public_port_sftp,
|
||||
],
|
||||
'description' => $server->description,
|
||||
'limits' => [
|
||||
|
@ -55,7 +55,7 @@ class ServerTransformer extends BaseClientTransformer
|
|||
'io' => $server->io,
|
||||
'cpu' => $server->cpu,
|
||||
'threads' => $server->threads,
|
||||
'oom_disabled' => $server->oom_disabled,
|
||||
'oom_killer' => $server->oom_killer,
|
||||
],
|
||||
'invocation' => $service->handle($server, !$user->can(Permission::ACTION_STARTUP_READ, $server)),
|
||||
'docker_image' => $server->image,
|
||||
|
@ -66,22 +66,16 @@ class ServerTransformer extends BaseClientTransformer
|
|||
'backups' => $server->backup_limit,
|
||||
],
|
||||
'status' => $server->status,
|
||||
// This field is deprecated, please use "status".
|
||||
'is_suspended' => $server->isSuspended(),
|
||||
// This field is deprecated, please use "status".
|
||||
'is_installing' => !$server->isInstalled(),
|
||||
'is_transferring' => !is_null($server->transfer),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the allocations associated with this server.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Transformer\InvalidTransformerLevelException
|
||||
*/
|
||||
public function includeAllocations(Server $server): Collection
|
||||
{
|
||||
$transformer = $this->makeTransformer(AllocationTransformer::class);
|
||||
$transformer = new AllocationTransformer();
|
||||
|
||||
$user = $this->request->user();
|
||||
// While we include this permission, we do need to actually handle it slightly different here
|
||||
|
@ -95,42 +89,31 @@ class ServerTransformer extends BaseClientTransformer
|
|||
$primary = clone $server->allocation;
|
||||
$primary->notes = null;
|
||||
|
||||
return $this->collection([$primary], $transformer, Allocation::RESOURCE_NAME);
|
||||
return $this->collection([$primary], $transformer);
|
||||
}
|
||||
|
||||
return $this->collection($server->allocations, $transformer, Allocation::RESOURCE_NAME);
|
||||
return $this->collection($server->allocations, $transformer);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Pterodactyl\Exceptions\Transformer\InvalidTransformerLevelException
|
||||
*/
|
||||
public function includeVariables(Server $server): Collection|NullResource
|
||||
{
|
||||
if (!$this->request->user()->can(Permission::ACTION_STARTUP_READ, $server)) {
|
||||
return $this->null();
|
||||
}
|
||||
|
||||
return $this->collection(
|
||||
$server->variables->where('user_viewable', true),
|
||||
$this->makeTransformer(EggVariableTransformer::class),
|
||||
EggVariable::RESOURCE_NAME
|
||||
);
|
||||
return $this->collection($server->variables->where('user_viewable', true), new EggVariableTransformer());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the egg associated with this server.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Transformer\InvalidTransformerLevelException
|
||||
*/
|
||||
public function includeEgg(Server $server): Item
|
||||
{
|
||||
return $this->item($server->egg, $this->makeTransformer(EggTransformer::class), Egg::RESOURCE_NAME);
|
||||
return $this->item($server->egg, new EggTransformer());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the subusers associated with this server.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Transformer\InvalidTransformerLevelException
|
||||
*/
|
||||
public function includeSubusers(Server $server): Collection|NullResource
|
||||
{
|
||||
|
@ -138,6 +121,6 @@ class ServerTransformer extends BaseClientTransformer
|
|||
return $this->null();
|
||||
}
|
||||
|
||||
return $this->collection($server->subusers, $this->makeTransformer(SubuserTransformer::class), Subuser::RESOURCE_NAME);
|
||||
return $this->collection($server->subusers, new SubuserTransformer());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,8 +3,9 @@
|
|||
namespace Pterodactyl\Transformers\Api\Client;
|
||||
|
||||
use Illuminate\Support\Arr;
|
||||
use Pterodactyl\Transformers\Api\Transformer;
|
||||
|
||||
class StatsTransformer extends BaseClientTransformer
|
||||
class StatsTransformer extends Transformer
|
||||
{
|
||||
public function getResourceName(): string
|
||||
{
|
||||
|
@ -15,18 +16,18 @@ class StatsTransformer extends BaseClientTransformer
|
|||
* Transform stats from the daemon into a result set that can be used in
|
||||
* the client API.
|
||||
*/
|
||||
public function transform(array $data): array
|
||||
public function transform(array $model): array
|
||||
{
|
||||
return [
|
||||
'current_state' => Arr::get($data, 'state', 'stopped'),
|
||||
'is_suspended' => Arr::get($data, 'is_suspended', false),
|
||||
'current_state' => Arr::get($model, 'state', 'stopped'),
|
||||
'is_suspended' => Arr::get($model, 'is_suspended', false),
|
||||
'resources' => [
|
||||
'memory_bytes' => Arr::get($data, 'utilization.memory_bytes', 0),
|
||||
'cpu_absolute' => Arr::get($data, 'utilization.cpu_absolute', 0),
|
||||
'disk_bytes' => Arr::get($data, 'utilization.disk_bytes', 0),
|
||||
'network_rx_bytes' => Arr::get($data, 'utilization.network.rx_bytes', 0),
|
||||
'network_tx_bytes' => Arr::get($data, 'utilization.network.tx_bytes', 0),
|
||||
'uptime' => Arr::get($data, 'utilization.uptime', 0),
|
||||
'memory_bytes' => Arr::get($model, 'utilization.memory_bytes', 0),
|
||||
'cpu_absolute' => Arr::get($model, 'utilization.cpu_absolute', 0),
|
||||
'disk_bytes' => Arr::get($model, 'utilization.disk_bytes', 0),
|
||||
'network_rx_bytes' => Arr::get($model, 'utilization.network.rx_bytes', 0),
|
||||
'network_tx_bytes' => Arr::get($model, 'utilization.network.tx_bytes', 0),
|
||||
'uptime' => Arr::get($model, 'utilization.uptime', 0),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
|
|
@ -3,8 +3,9 @@
|
|||
namespace Pterodactyl\Transformers\Api\Client;
|
||||
|
||||
use Pterodactyl\Models\Subuser;
|
||||
use Pterodactyl\Transformers\Api\Transformer;
|
||||
|
||||
class SubuserTransformer extends BaseClientTransformer
|
||||
class SubuserTransformer extends Transformer
|
||||
{
|
||||
/**
|
||||
* Return the resource name for the JSONAPI output.
|
||||
|
@ -16,13 +17,11 @@ class SubuserTransformer extends BaseClientTransformer
|
|||
|
||||
/**
|
||||
* Transforms a subuser into a model that can be shown to a front-end user.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Transformer\InvalidTransformerLevelException
|
||||
*/
|
||||
public function transform(Subuser $model): array
|
||||
{
|
||||
return array_merge(
|
||||
$this->makeTransformer(UserTransformer::class)->transform($model->user),
|
||||
(new UserTransformer())->transform($model->user),
|
||||
['permissions' => $model->permissions]
|
||||
);
|
||||
}
|
||||
|
|
|
@ -3,8 +3,9 @@
|
|||
namespace Pterodactyl\Transformers\Api\Client;
|
||||
|
||||
use Pterodactyl\Models\Task;
|
||||
use Pterodactyl\Transformers\Api\Transformer;
|
||||
|
||||
class TaskTransformer extends BaseClientTransformer
|
||||
class TaskTransformer extends Transformer
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
@ -27,8 +28,8 @@ class TaskTransformer extends BaseClientTransformer
|
|||
'time_offset' => $model->time_offset,
|
||||
'is_queued' => $model->is_queued,
|
||||
'continue_on_failure' => $model->continue_on_failure,
|
||||
'created_at' => $model->created_at->toAtomString(),
|
||||
'updated_at' => $model->updated_at->toAtomString(),
|
||||
'created_at' => self::formatTimestamp($model->created_at),
|
||||
'updated_at' => self::formatTimestamp($model->updated_at),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,8 +3,9 @@
|
|||
namespace Pterodactyl\Transformers\Api\Client;
|
||||
|
||||
use Pterodactyl\Models\UserSSHKey;
|
||||
use Pterodactyl\Transformers\Api\Transformer;
|
||||
|
||||
class UserSSHKeyTransformer extends BaseClientTransformer
|
||||
class UserSSHKeyTransformer extends Transformer
|
||||
{
|
||||
public function getResourceName(): string
|
||||
{
|
||||
|
@ -20,7 +21,7 @@ class UserSSHKeyTransformer extends BaseClientTransformer
|
|||
'name' => $model->name,
|
||||
'fingerprint' => $model->fingerprint,
|
||||
'public_key' => $model->public_key,
|
||||
'created_at' => $model->created_at->toAtomString(),
|
||||
'created_at' => self::formatTimestamp($model->created_at),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
|
||||
namespace Pterodactyl\Transformers\Api\Client;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
use Pterodactyl\Models\User;
|
||||
use Pterodactyl\Transformers\Api\Transformer;
|
||||
|
||||
class UserTransformer extends BaseClientTransformer
|
||||
class UserTransformer extends Transformer
|
||||
{
|
||||
/**
|
||||
* Return the resource name for the JSONAPI output.
|
||||
|
@ -25,9 +25,9 @@ class UserTransformer extends BaseClientTransformer
|
|||
'uuid' => $model->uuid,
|
||||
'username' => $model->username,
|
||||
'email' => $model->email,
|
||||
'image' => 'https://gravatar.com/avatar/' . md5(Str::lower($model->email)),
|
||||
'image' => $model->avatar_url,
|
||||
'2fa_enabled' => $model->use_totp,
|
||||
'created_at' => $model->created_at->toAtomString(),
|
||||
'created_at' => self::formatTimestamp($model->created_at),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
154
app/Transformers/Api/Transformer.php
Normal file
154
app/Transformers/Api/Transformer.php
Normal file
|
@ -0,0 +1,154 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Transformers\Api;
|
||||
|
||||
use Carbon\CarbonImmutable;
|
||||
use Carbon\CarbonInterface;
|
||||
use Illuminate\Http\Request;
|
||||
use Pterodactyl\Models\User;
|
||||
use Webmozart\Assert\Assert;
|
||||
use League\Fractal\Resource\Item;
|
||||
use Illuminate\Container\Container;
|
||||
use League\Fractal\Resource\Collection;
|
||||
use League\Fractal\TransformerAbstract;
|
||||
|
||||
/**
|
||||
* @method array transform(\Pterodactyl\Models\Model $model)
|
||||
*/
|
||||
abstract class Transformer extends TransformerAbstract
|
||||
{
|
||||
protected static string $timezone = 'UTC';
|
||||
|
||||
protected Request $request;
|
||||
|
||||
/**
|
||||
* Sets the request instance onto the transformer abstract from the container. This
|
||||
* will also automatically handle dependency injection for the class implementing
|
||||
* this abstract.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->request = Container::getInstance()->make('request');
|
||||
|
||||
if (method_exists($this, 'handle')) {
|
||||
Container::getInstance()->call([$this, 'handle']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the resource name for the transformed item.
|
||||
*/
|
||||
abstract public function getResourceName(): string;
|
||||
|
||||
/**
|
||||
* Returns the authorized user for the request.
|
||||
*/
|
||||
protected function user(): User
|
||||
{
|
||||
return $this->request->user();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the user making this request is authorized to access the given
|
||||
* resource on the API. This is used when requested included items to ensure that
|
||||
* the user and key are authorized to see the result.
|
||||
*
|
||||
* TODO: implement this with the new API key formats.
|
||||
*/
|
||||
protected function authorize(string $resource): bool
|
||||
{
|
||||
return $this->request->user() instanceof User;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @param mixed $data
|
||||
* @param callable|\League\Fractal\TransformerAbstract $transformer
|
||||
*/
|
||||
protected function item($data, $transformer, ?string $resourceKey = null): Item
|
||||
{
|
||||
if (!$transformer instanceof \Closure) {
|
||||
self::assertSameNamespace($transformer);
|
||||
}
|
||||
|
||||
$item = parent::item($data, $transformer, $resourceKey);
|
||||
|
||||
if (!$item->getResourceKey() && method_exists($transformer, 'getResourceName')) {
|
||||
$item->setResourceKey($transformer->getResourceName());
|
||||
}
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @param mixed $data
|
||||
* @param callable|\League\Fractal\TransformerAbstract $transformer
|
||||
*/
|
||||
protected function collection($data, $transformer, ?string $resourceKey = null): Collection
|
||||
{
|
||||
if (!$transformer instanceof \Closure) {
|
||||
self::assertSameNamespace($transformer);
|
||||
}
|
||||
|
||||
$collection = parent::collection($data, $transformer, $resourceKey);
|
||||
|
||||
if (!$collection->getResourceKey() && method_exists($transformer, 'getResourceName')) {
|
||||
$collection->setResourceKey($transformer->getResourceName());
|
||||
}
|
||||
|
||||
return $collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the default timezone to use for transformed responses. Pass a null value
|
||||
* to return back to the default timezone (UTC).
|
||||
*/
|
||||
public static function setTimezone(string $tz = null)
|
||||
{
|
||||
static::$timezone = $tz ?? 'UTC';
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given transformer is the same base namespace as the class that
|
||||
* implements this abstract transformer class. This prevents a client or application
|
||||
* transformer from unintentionally transforming a resource using an unexpected type.
|
||||
*
|
||||
* @param callable|\League\Fractal\TransformerAbstract $transformer
|
||||
*/
|
||||
protected static function assertSameNamespace($transformer)
|
||||
{
|
||||
Assert::subclassOf($transformer, TransformerAbstract::class);
|
||||
|
||||
$namespace = substr(get_class($transformer), 0, strlen(class_basename($transformer)) * -1);
|
||||
$expected = substr(static::class, 0, strlen(class_basename(static::class)) * -1);
|
||||
|
||||
Assert::same($namespace, $expected, 'Cannot invoke a new transformer (%s) that is not in the same namespace (%s).');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an ISO-8601 formatted timestamp to use in API responses. This
|
||||
* time is returned in the default transformer timezone if no timezone value
|
||||
* is provided.
|
||||
*
|
||||
* If no time is provided a null value is returned.
|
||||
*
|
||||
* @param string|\DateTimeInterface|null $timestamp
|
||||
*/
|
||||
protected static function formatTimestamp($timestamp, string $tz = null): ?string
|
||||
{
|
||||
if (empty($timestamp)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($timestamp instanceof \DateTimeInterface) {
|
||||
$value = CarbonImmutable::instance($timestamp);
|
||||
} else {
|
||||
$value = CarbonImmutable::createFromFormat(CarbonInterface::DEFAULT_TO_STRING_FORMAT, $timestamp);
|
||||
}
|
||||
|
||||
return $value->setTimezone($tz ?? self::$timezone)->toAtomString();
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue