mirror of
https://github.com/pelican-dev/panel.git
synced 2026-07-18 05:03:56 +03:00
Compare commits
1 Commits
server-use
...
lance/jwt-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
28ad3c9c0f |
12
app/Enums/JwtScope.php
Normal file
12
app/Enums/JwtScope.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
enum JwtScope: string
|
||||
{
|
||||
case Websocket = 'websocket';
|
||||
case FileUpload = 'file-upload';
|
||||
case FileDownload = 'file-download';
|
||||
case BackupDownload = 'backup-download';
|
||||
case ServerTransfer = 'transfer';
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Filament\Server\Resources\Files\Pages;
|
||||
|
||||
use App\Enums\JwtScope;
|
||||
use App\Enums\SubuserPermission;
|
||||
use App\Facades\Activity;
|
||||
use App\Filament\Server\Resources\Files\FileResource;
|
||||
@@ -44,6 +45,7 @@ class DownloadFiles extends Page
|
||||
'file_path' => rawurldecode($path),
|
||||
'server_uuid' => $server->uuid,
|
||||
])
|
||||
->setScopes(JwtScope::FileDownload)
|
||||
->handle($server->node, user()?->id . $server->uuid);
|
||||
|
||||
Activity::event('server:file.download')
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Filament\Server\Widgets;
|
||||
|
||||
use App\Enums\JwtScope;
|
||||
use App\Enums\SubuserPermission;
|
||||
use App\Exceptions\Http\HttpForbiddenException;
|
||||
use App\Livewire\AlertBanner;
|
||||
@@ -59,6 +60,7 @@ class ServerConsole extends Widget
|
||||
'server_uuid' => $this->server->uuid,
|
||||
'permissions' => $permissions,
|
||||
])
|
||||
->setScopes(JwtScope::Websocket)
|
||||
->handle($this->server->node, $this->user->id . $this->server->uuid)->toString();
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Http\Controllers\Api\Client\Servers;
|
||||
|
||||
use App\Enums\JwtScope;
|
||||
use App\Facades\Activity;
|
||||
use App\Http\Controllers\Api\Client\ClientApiController;
|
||||
use App\Http\Requests\Api\Client\Servers\Files\ChmodFilesRequest;
|
||||
@@ -98,6 +99,7 @@ class FileController extends ClientApiController
|
||||
'file_path' => rawurldecode($request->get('file')),
|
||||
'server_uuid' => $server->uuid,
|
||||
])
|
||||
->setScopes(JwtScope::FileDownload)
|
||||
->handle($server->node, $request->user()->id . $server->uuid);
|
||||
|
||||
Activity::event('server:file.download')->property('file', $request->get('file'))->log();
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Http\Controllers\Api\Client\Servers;
|
||||
|
||||
use App\Enums\JwtScope;
|
||||
use App\Http\Controllers\Api\Client\ClientApiController;
|
||||
use App\Http\Requests\Api\Client\Servers\Files\UploadFileRequest;
|
||||
use App\Models\Server;
|
||||
@@ -47,6 +48,7 @@ class FileUploadController extends ClientApiController
|
||||
->setExpiresAt(CarbonImmutable::now()->addMinutes(15))
|
||||
->setUser($user)
|
||||
->setClaims(['server_uuid' => $server->uuid])
|
||||
->setScopes(JwtScope::FileUpload)
|
||||
->handle($server->node, $user->id . $server->uuid);
|
||||
|
||||
return sprintf(
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Http\Controllers\Api\Client\Servers;
|
||||
|
||||
use App\Enums\JwtScope;
|
||||
use App\Enums\SubuserPermission;
|
||||
use App\Exceptions\Http\HttpForbiddenException;
|
||||
use App\Http\Controllers\Api\Client\ClientApiController;
|
||||
@@ -63,6 +64,7 @@ class WebsocketController extends ClientApiController
|
||||
'server_uuid' => $server->uuid,
|
||||
'permissions' => $permissions,
|
||||
])
|
||||
->setScopes(JwtScope::Websocket)
|
||||
->handle($node, $user->id . $server->uuid);
|
||||
|
||||
$socket = str_replace(['https://', 'http://'], ['wss://', 'ws://'], $node->getConnectionAddress());
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use App\Enums\JwtScope;
|
||||
use App\Enums\TablerIcon;
|
||||
use App\Models\Node;
|
||||
use App\Services\Nodes\NodeJWTService;
|
||||
@@ -52,6 +53,7 @@ class NodeClientConnectivity extends Component
|
||||
'server_uuid' => $server->uuid,
|
||||
'permissions' => $permissions,
|
||||
])
|
||||
->setScopes(JwtScope::Websocket)
|
||||
->handle($this->node, $user->id . $server->uuid)->toString();
|
||||
|
||||
$wsUrl = str_replace(['https://', 'http://'], ['wss://', 'ws://'], $this->node->getConnectionAddress());
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Services\Backups;
|
||||
|
||||
use App\Enums\JwtScope;
|
||||
use App\Extensions\Backups\BackupManager;
|
||||
use App\Extensions\Filesystem\S3Filesystem;
|
||||
use App\Models\Backup;
|
||||
@@ -33,6 +34,7 @@ class DownloadLinkService
|
||||
'backup_uuid' => $backup->uuid,
|
||||
'server_uuid' => $backup->server->uuid,
|
||||
])
|
||||
->setScopes(JwtScope::BackupDownload)
|
||||
->handle($backup->server->node, $user->id . $backup->server->uuid);
|
||||
|
||||
return sprintf('%s/download/backup?token=%s', $backup->server->node->getConnectionAddress(), $token->toString());
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Services\Nodes;
|
||||
|
||||
use App\Enums\JwtScope;
|
||||
use App\Extensions\Lcobucci\JWT\Encoding\TimestampDates;
|
||||
use App\Models\Node;
|
||||
use App\Models\User;
|
||||
@@ -12,12 +13,16 @@ use Lcobucci\JWT\Configuration;
|
||||
use Lcobucci\JWT\Signer\Hmac\Sha256;
|
||||
use Lcobucci\JWT\Signer\Key\InMemory;
|
||||
use Lcobucci\JWT\UnencryptedToken;
|
||||
use Webmozart\Assert\Assert;
|
||||
|
||||
class NodeJWTService
|
||||
{
|
||||
/** @var array<array-key, mixed> */
|
||||
private array $claims = [];
|
||||
|
||||
/** @var JwtScope[] */
|
||||
private array $scopes = [];
|
||||
|
||||
private ?User $user = null;
|
||||
|
||||
private DateTimeImmutable $expiresAt;
|
||||
@@ -36,6 +41,13 @@ class NodeJWTService
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setScopes(JwtScope ...$scopes): self
|
||||
{
|
||||
$this->scopes = $scopes;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attaches a user to the JWT being created and will automatically inject the
|
||||
* "user_uuid" key into the final claims array with the user's UUID.
|
||||
@@ -64,9 +76,9 @@ class NodeJWTService
|
||||
/**
|
||||
* Generate a new JWT for a given node.
|
||||
*/
|
||||
public function handle(Node $node, ?string $identifiedBy, string $algo = 'sha256'): UnencryptedToken
|
||||
public function handle(Node $node, ?string $identifiedBy): UnencryptedToken
|
||||
{
|
||||
$identifier = hash($algo, $identifiedBy);
|
||||
$identifier = hash('sha256', $identifiedBy);
|
||||
$config = Configuration::forSymmetricSigner(new Sha256(), InMemory::plainText($node->daemon_token));
|
||||
|
||||
$builder = $config->builder(new TimestampDates())
|
||||
@@ -89,6 +101,10 @@ class NodeJWTService
|
||||
$builder = $builder->withClaim($key, $value);
|
||||
}
|
||||
|
||||
Assert::notEmpty($this->scopes, 'Cannot generate a JWT without providing at least one scope.');
|
||||
|
||||
$builder = $builder->withClaim('scope', implode(' ', array_map(fn (JwtScope $scope) => $scope->value, $this->scopes)));
|
||||
|
||||
if (!is_null($this->user)) {
|
||||
$builder = $builder->withClaim('user_uuid', $this->user->uuid);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Services\Servers;
|
||||
|
||||
use App\Enums\JwtScope;
|
||||
use App\Models\Allocation;
|
||||
use App\Models\Backup;
|
||||
use App\Models\Node;
|
||||
@@ -100,7 +101,8 @@ class TransferServerService
|
||||
$token = $this->nodeJWTService
|
||||
->setExpiresAt(CarbonImmutable::now()->addMinutes(15))
|
||||
->setSubject($server->uuid)
|
||||
->handle($transfer->newNode, $server->uuid, 'sha256');
|
||||
->setScopes(JwtScope::ServerTransfer)
|
||||
->handle($transfer->newNode, $server->uuid);
|
||||
|
||||
// Notify the source node of the pending outgoing transfer.
|
||||
$this->notify($transfer, $token, $backup_uuid);
|
||||
|
||||
Reference in New Issue
Block a user