33namespace Pterodactyl \Http \Controllers \Api \Client \Servers ;
44
55use Carbon \CarbonImmutable ;
6+ use Pterodactyl \Models \User ;
67use Pterodactyl \Models \Backup ;
78use Pterodactyl \Models \Server ;
9+ use Illuminate \Http \JsonResponse ;
810use Pterodactyl \Services \Nodes \NodeJWTService ;
911use Illuminate \Contracts \Routing \ResponseFactory ;
12+ use Pterodactyl \Extensions \Backups \BackupManager ;
1013use Pterodactyl \Repositories \Wings \DaemonBackupRepository ;
1114use Pterodactyl \Http \Controllers \Api \Client \ClientApiController ;
15+ use Symfony \Component \HttpKernel \Exception \BadRequestHttpException ;
1216use Pterodactyl \Http \Requests \Api \Client \Servers \Backups \DownloadBackupRequest ;
1317
1418class DownloadBackupController extends ClientApiController
@@ -28,23 +32,31 @@ class DownloadBackupController extends ClientApiController
2832 */
2933 private $ jwtService ;
3034
35+ /**
36+ * @var \Pterodactyl\Extensions\Backups\BackupManager
37+ */
38+ private $ backupManager ;
39+
3140 /**
3241 * DownloadBackupController constructor.
3342 *
3443 * @param \Pterodactyl\Repositories\Wings\DaemonBackupRepository $daemonBackupRepository
3544 * @param \Pterodactyl\Services\Nodes\NodeJWTService $jwtService
45+ * @param \Pterodactyl\Extensions\Backups\BackupManager $backupManager
3646 * @param \Illuminate\Contracts\Routing\ResponseFactory $responseFactory
3747 */
3848 public function __construct (
3949 DaemonBackupRepository $ daemonBackupRepository ,
4050 NodeJWTService $ jwtService ,
51+ BackupManager $ backupManager ,
4152 ResponseFactory $ responseFactory
4253 ) {
4354 parent ::__construct ();
4455
4556 $ this ->daemonBackupRepository = $ daemonBackupRepository ;
4657 $ this ->responseFactory = $ responseFactory ;
4758 $ this ->jwtService = $ jwtService ;
59+ $ this ->backupManager = $ backupManager ;
4860 }
4961
5062 /**
@@ -55,27 +67,78 @@ public function __construct(
5567 * @param \Pterodactyl\Http\Requests\Api\Client\Servers\Backups\DownloadBackupRequest $request
5668 * @param \Pterodactyl\Models\Server $server
5769 * @param \Pterodactyl\Models\Backup $backup
58- * @return array
70+ * @return \Illuminate\Http\JsonResponse
5971 */
6072 public function __invoke (DownloadBackupRequest $ request , Server $ server , Backup $ backup )
73+ {
74+ switch ($ backup ->disk ) {
75+ case Backup::ADAPTER_WINGS :
76+ $ url = $ this ->getLocalBackupUrl ($ backup , $ server , $ request ->user ());
77+ break ;
78+ case Backup::ADAPTER_AWS_S3 :
79+ $ url = $ this ->getS3BackupUrl ($ backup , $ server );
80+ break ;
81+ default :
82+ throw new BadRequestHttpException ;
83+ }
84+
85+ return JsonResponse::create ([
86+ 'object ' => 'signed_url ' ,
87+ 'attributes ' => [
88+ 'url ' => $ url ,
89+ ],
90+ ]);
91+ }
92+
93+ /**
94+ * Returns a signed URL that allows us to download a file directly out of a non-public
95+ * S3 bucket by using a signed URL.
96+ *
97+ * @param \Pterodactyl\Models\Backup $backup
98+ * @param \Pterodactyl\Models\Server $server
99+ * @return string
100+ */
101+ protected function getS3BackupUrl (Backup $ backup , Server $ server )
102+ {
103+ /** @var \League\Flysystem\AwsS3v3\AwsS3Adapter $adapter */
104+ $ adapter = $ this ->backupManager ->adapter (Backup::ADAPTER_AWS_S3 );
105+
106+ $ client = $ adapter ->getClient ();
107+
108+ $ request = $ client ->createPresignedRequest (
109+ $ client ->getCommand ('GetObject ' , [
110+ 'Bucket ' => $ adapter ->getBucket (),
111+ 'Key ' => sprintf ('%s/%s.tar.gz ' , $ server ->uuid , $ backup ->uuid ),
112+ 'ContentType ' => 'application/x-gzip ' ,
113+ ]),
114+ CarbonImmutable::now ()->addMinutes (5 )
115+ );
116+
117+ return $ request ->getUri ()->__toString ();
118+ }
119+
120+ /**
121+ * Returns a download link a backup stored on a wings instance.
122+ *
123+ * @param \Pterodactyl\Models\Backup $backup
124+ * @param \Pterodactyl\Models\Server $server
125+ * @param \Pterodactyl\Models\User $user
126+ * @return string
127+ */
128+ protected function getLocalBackupUrl (Backup $ backup , Server $ server , User $ user )
61129 {
62130 $ token = $ this ->jwtService
63131 ->setExpiresAt (CarbonImmutable::now ()->addMinutes (15 ))
64132 ->setClaims ([
65133 'backup_uuid ' => $ backup ->uuid ,
66134 'server_uuid ' => $ server ->uuid ,
67135 ])
68- ->handle ($ server ->node , $ request -> user () ->id . $ server ->uuid );
136+ ->handle ($ server ->node , $ user ->id . $ server ->uuid );
69137
70- return [
71- 'object ' => 'signed_url ' ,
72- 'attributes ' => [
73- 'url ' => sprintf (
74- '%s/download/backup?token=%s ' ,
75- $ server ->node ->getConnectionAddress (),
76- $ token ->__toString ()
77- ),
78- ],
79- ];
138+ return sprintf (
139+ '%s/download/backup?token=%s ' ,
140+ $ server ->node ->getConnectionAddress (),
141+ $ token ->__toString ()
142+ );
80143 }
81144}
0 commit comments