|
|
@@ -6,7 +6,7 @@ namespace App\State\Provider\Core;
|
|
|
use ApiPlatform\Metadata\GetCollection;
|
|
|
use ApiPlatform\Metadata\Operation;
|
|
|
use ApiPlatform\State\ProviderInterface;
|
|
|
-use App\ApiResources\DownloadRequest;
|
|
|
+use App\ApiResources\Core\File\DownloadRequest;
|
|
|
use App\Enum\Core\FileStatusEnum;
|
|
|
use App\Repository\Core\FileRepository;
|
|
|
use App\Service\File\Exception\FileNotFoundException;
|
|
|
@@ -15,33 +15,21 @@ use RuntimeException;
|
|
|
use Symfony\Component\HttpFoundation\HeaderUtils;
|
|
|
use Symfony\Component\HttpFoundation\RedirectResponse;
|
|
|
use Symfony\Component\HttpFoundation\Response;
|
|
|
-use Symfony\Bundle\SecurityBundle\Security;
|
|
|
|
|
|
/**
|
|
|
* Custom provider pour le téléchargement des fichiers du LocalStorage
|
|
|
*/
|
|
|
final class DownloadRequestProvider implements ProviderInterface
|
|
|
{
|
|
|
- // Internal ips allowed to access private files without being authenticated
|
|
|
- const INTERNAL_IPS = [
|
|
|
- '/^127\.0\.0\.[0-1]$/',
|
|
|
- '/^localhost$/',
|
|
|
- '/^10\.8\.0\.\d{1,3}$/', // VPN
|
|
|
- '/^141\.94\.117\.[33-61]$/', // internal public ips
|
|
|
- '/^172\.20\.\d{1,3}\.\d{1,3}$/', // docker
|
|
|
- ];
|
|
|
-
|
|
|
public function __construct(
|
|
|
- private FileRepository $fileRepository,
|
|
|
- private FileManager $fileManager,
|
|
|
- private Security $security,
|
|
|
- )
|
|
|
- {}
|
|
|
+ private readonly FileRepository $fileRepository,
|
|
|
+ private readonly FileManager $fileManager,
|
|
|
+ ) {}
|
|
|
|
|
|
/**
|
|
|
* @param string $resourceClass
|
|
|
* @param string|null $operationName
|
|
|
- * @param mixed[] $context
|
|
|
+ * @param array $context
|
|
|
* @return bool
|
|
|
*/
|
|
|
public function supports(string $resourceClass, string $operationName = null, array $context = []): bool
|
|
|
@@ -49,26 +37,10 @@ final class DownloadRequestProvider implements ProviderInterface
|
|
|
return DownloadRequest::class === $resourceClass;
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * Returns true if the client Ip is allowed to access restricted content without auth
|
|
|
- *
|
|
|
- * @param string $clientIp
|
|
|
- * @return bool
|
|
|
- */
|
|
|
- private function isInternalIp(string $clientIp): bool
|
|
|
- {
|
|
|
- foreach (self::INTERNAL_IPS as $ipRule) {
|
|
|
- if (preg_match($ipRule, $clientIp)) {
|
|
|
- return true;
|
|
|
- }
|
|
|
- }
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
/**
|
|
|
* @param Operation $operation
|
|
|
- * @param mixed[] $uriVariables
|
|
|
- * @param mixed[] $context
|
|
|
+ * @param array $uriVariables
|
|
|
+ * @param array $context
|
|
|
* @return Response|RedirectResponse
|
|
|
* @throws FileNotFoundException
|
|
|
*/
|
|
|
@@ -78,22 +50,27 @@ final class DownloadRequestProvider implements ProviderInterface
|
|
|
throw new RuntimeException('not supported', 500);
|
|
|
}
|
|
|
|
|
|
- $id = $uriVariables['id'];
|
|
|
- $file = $this->fileRepository->find($id);
|
|
|
+ $id = $uriVariables['fileId'];
|
|
|
+
|
|
|
+ return $this->serveFile($id);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param int $fileId
|
|
|
+ * @return Response
|
|
|
+ * @throws FileNotFoundException
|
|
|
+ */
|
|
|
+ protected function serveFile(int $fileId): Response {
|
|
|
+ $file = $this->fileRepository->find($fileId);
|
|
|
+
|
|
|
if (empty($file)) {
|
|
|
- throw new RuntimeException("File " . $id . " does not exist; abort.");
|
|
|
+ throw new RuntimeException("File " . $fileId . " does not exist; abort.");
|
|
|
}
|
|
|
if ($file->getStatus() !== FileStatusEnum::READY()->getValue()) {
|
|
|
- throw new RuntimeException("File " . $id . " has " . $file->getStatus() . " status; abort.");
|
|
|
+ throw new RuntimeException("File " . $fileId . " has " . $file->getStatus() . " status; abort.");
|
|
|
}
|
|
|
|
|
|
- // This is a request from an authorized IP
|
|
|
- $clientIp = $_SERVER['REMOTE_ADDR'];
|
|
|
- $internalIp = $this->isInternalIp($clientIp);
|
|
|
-
|
|
|
- // Read the file
|
|
|
- $token = $internalIp ? null : $this->security->getToken();
|
|
|
- $content = $this->fileManager->read($file, $token);
|
|
|
+ $content = $this->fileManager->read($file);
|
|
|
|
|
|
// Build the response and attach the file to it
|
|
|
// @see https://symfony.com/doc/current/components/http_foundation.html#serving-files
|
|
|
@@ -113,4 +90,5 @@ final class DownloadRequestProvider implements ProviderInterface
|
|
|
|
|
|
return $response;
|
|
|
}
|
|
|
+
|
|
|
}
|