mirror of
https://github.com/pelican-dev/panel.git
synced 2026-02-27 16:03:16 +03:00
66 lines
2.4 KiB
PHP
66 lines
2.4 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Api\Remote\Backups;
|
|
|
|
use App\Exceptions\Http\HttpForbiddenException;
|
|
use App\Extensions\BackupAdapter\BackupAdapterService;
|
|
use App\Extensions\BackupAdapter\Schemas\S3BackupSchema;
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\Backup;
|
|
use App\Models\Node;
|
|
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
|
|
use Symfony\Component\HttpKernel\Exception\ConflictHttpException;
|
|
|
|
class BackupRemoteUploadController extends Controller
|
|
{
|
|
public const DEFAULT_MAX_PART_SIZE = 5 * 1024 * 1024 * 1024;
|
|
|
|
/**
|
|
* BackupRemoteUploadController constructor.
|
|
*/
|
|
public function __construct(private BackupAdapterService $backupService) {}
|
|
|
|
/**
|
|
* Returns the required presigned urls to upload a backup to S3 cloud storage.
|
|
*
|
|
* @throws BadRequestHttpException
|
|
* @throws ModelNotFoundException
|
|
* @throws HttpForbiddenException
|
|
* @throws ConflictHttpException
|
|
*/
|
|
public function __invoke(Request $request, string $backup): JsonResponse
|
|
{
|
|
/** @var Node $node */
|
|
$node = $request->attributes->get('node');
|
|
|
|
$size = (int) $request->query('size');
|
|
if (empty($size)) {
|
|
throw new BadRequestHttpException('A non-empty "size" query parameter must be provided.');
|
|
}
|
|
|
|
$backup = Backup::where('uuid', $backup)->firstOrFail();
|
|
|
|
// Check that the backup is "owned" by the node making the request. This avoids other nodes
|
|
// from messing with backups that they don't own.
|
|
if ($backup->server->node_id !== $node->id) {
|
|
throw new HttpForbiddenException('You do not have permission to access that backup.');
|
|
}
|
|
|
|
// Prevent backups that have already been completed from trying to be uploaded again.
|
|
if (!is_null($backup->completed_at)) {
|
|
throw new ConflictHttpException('This backup is already in a completed state.');
|
|
}
|
|
|
|
// Ensure we are using the S3 schema.
|
|
$schema = $this->backupService->get($backup->backupHost->schema);
|
|
if (!$schema instanceof S3BackupSchema) {
|
|
throw new BadRequestHttpException('The configured backup schema is not an S3 compatible.');
|
|
}
|
|
|
|
return new JsonResponse($schema->getUploadParts($backup, $size));
|
|
}
|
|
}
|