Add Jwt Scopes from upstream (#2397)

This commit is contained in:
Charles
2026-06-17 06:42:03 -04:00
committed by GitHub
parent 475a454806
commit 0e75027c12
10 changed files with 47 additions and 3 deletions

View File

@@ -0,0 +1,12 @@
<?php
namespace App\Enums;
enum NodeJwtScope: string
{
case BackupDownload = 'backup-download';
case FileDownload = 'file-download';
case FileUpload = 'file-upload';
case ServerTransfer = 'transfer';
case Websocket = 'websocket';
}

View File

@@ -2,6 +2,7 @@
namespace App\Filament\Server\Resources\Files\Pages;
use App\Enums\NodeJwtScope;
use App\Enums\SubuserPermission;
use App\Facades\Activity;
use App\Filament\Server\Resources\Files\FileResource;
@@ -39,6 +40,7 @@ class DownloadFiles extends Page
$token = $this->nodeJWTService
->setExpiresAt(CarbonImmutable::now()->addMinutes(15))
->setScopes(NodeJwtScope::FileDownload)
->setUser(user())
->setClaims([
'file_path' => rawurldecode($path),

View File

@@ -2,6 +2,7 @@
namespace App\Filament\Server\Widgets;
use App\Enums\NodeJwtScope;
use App\Enums\SubuserPermission;
use App\Exceptions\Http\HttpForbiddenException;
use App\Livewire\AlertBanner;
@@ -54,6 +55,7 @@ class ServerConsole extends Widget
return $this->nodeJWTService
->setExpiresAt(now()->addMinutes(10)->toImmutable())
->setScopes(NodeJwtScope::Websocket)
->setUser($this->user)
->setClaims([
'server_uuid' => $this->server->uuid,

View File

@@ -2,6 +2,7 @@
namespace App\Http\Controllers\Api\Client\Servers;
use App\Enums\NodeJwtScope;
use App\Facades\Activity;
use App\Http\Controllers\Api\Client\ClientApiController;
use App\Http\Requests\Api\Client\Servers\Files\ChmodFilesRequest;
@@ -93,6 +94,7 @@ class FileController extends ClientApiController
{
$token = $this->jwtService
->setExpiresAt(CarbonImmutable::now()->addMinutes(15))
->setScopes(NodeJwtScope::FileDownload)
->setUser($request->user())
->setClaims([
'file_path' => rawurldecode($request->get('file')),

View File

@@ -2,6 +2,7 @@
namespace App\Http\Controllers\Api\Client\Servers;
use App\Enums\NodeJwtScope;
use App\Http\Controllers\Api\Client\ClientApiController;
use App\Http\Requests\Api\Client\Servers\Files\UploadFileRequest;
use App\Models\Server;
@@ -45,6 +46,7 @@ class FileUploadController extends ClientApiController
{
$token = $this->jwtService
->setExpiresAt(CarbonImmutable::now()->addMinutes(15))
->setScopes(NodeJwtScope::FileUpload)
->setUser($user)
->setClaims(['server_uuid' => $server->uuid])
->handle($server->node, $user->id . $server->uuid);

View File

@@ -2,6 +2,7 @@
namespace App\Http\Controllers\Api\Client\Servers;
use App\Enums\NodeJwtScope;
use App\Enums\SubuserPermission;
use App\Exceptions\Http\HttpForbiddenException;
use App\Http\Controllers\Api\Client\ClientApiController;
@@ -58,6 +59,7 @@ class WebsocketController extends ClientApiController
$token = $this->jwtService
->setExpiresAt(CarbonImmutable::now()->addMinutes(10))
->setScopes(NodeJwtScope::Websocket)
->setUser($request->user())
->setClaims([
'server_uuid' => $server->uuid,

View File

@@ -2,6 +2,7 @@
namespace App\Livewire;
use App\Enums\NodeJwtScope;
use App\Enums\TablerIcon;
use App\Models\Node;
use App\Services\Nodes\NodeJWTService;
@@ -47,6 +48,7 @@ class NodeClientConnectivity extends Component
$wsToken = $this->nodeJWTService
->setExpiresAt(now()->addMinute()->toImmutable())
->setScopes(NodeJwtScope::Websocket)
->setUser($user)
->setClaims([
'server_uuid' => $server->uuid,

View File

@@ -2,6 +2,7 @@
namespace App\Services\Backups;
use App\Enums\NodeJwtScope;
use App\Extensions\Backups\BackupManager;
use App\Extensions\Filesystem\S3Filesystem;
use App\Models\Backup;
@@ -28,6 +29,7 @@ class DownloadLinkService
$token = $this->jwtService
->setExpiresAt(CarbonImmutable::now()->addMinutes(15))
->setScopes(NodeJwtScope::BackupDownload)
->setUser($user)
->setClaims([
'backup_uuid' => $backup->uuid,

View File

@@ -2,6 +2,7 @@
namespace App\Services\Nodes;
use App\Enums\NodeJwtScope;
use App\Extensions\Lcobucci\JWT\Encoding\TimestampDates;
use App\Models\Node;
use App\Models\User;
@@ -12,6 +13,7 @@ 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
{
@@ -24,6 +26,9 @@ class NodeJWTService
private ?string $subject = null;
/** @var NodeJwtScope[] */
private array $scopes;
/**
* Set the claims to include in this JWT.
*
@@ -64,9 +69,11 @@ 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);
Assert::notEmpty($this->scopes, 'Cannot generate a JWT without providing at least one scope.');
$identifier = hash('sha256', $identifiedBy);
$config = Configuration::forSymmetricSigner(new Sha256(), InMemory::plainText($node->daemon_token));
$builder = $config->builder(new TimestampDates())
@@ -93,8 +100,17 @@ class NodeJWTService
$builder = $builder->withClaim('user_uuid', $this->user->uuid);
}
$builder = $builder->withClaim('scope', implode(' ', array_map(fn ($scope) => $scope->value, $this->scopes)));
return $builder
->withClaim('unique_id', Str::random())
->getToken($config->signer(), $config->signingKey());
}
public function setScopes(NodeJwtScope ...$scopes): self
{
$this->scopes = $scopes;
return $this;
}
}

View File

@@ -2,6 +2,7 @@
namespace App\Services\Servers;
use App\Enums\NodeJwtScope;
use App\Models\Allocation;
use App\Models\Backup;
use App\Models\Node;
@@ -99,8 +100,9 @@ class TransferServerService
// Generate a token for the destination node that the source node can use to authenticate with.
$token = $this->nodeJWTService
->setExpiresAt(CarbonImmutable::now()->addMinutes(15))
->setScopes(NodeJwtScope::ServerTransfer)
->setSubject($server->uuid)
->handle($transfer->newNode, $server->uuid, 'sha256');
->handle($transfer->newNode, $server->uuid);
// Notify the source node of the pending outgoing transfer.
$this->notify($transfer, $token, $backup_uuid);