浏览代码

implements Api1RequestService and files serving from api1

Olivier Massot 3 年之前
父节点
当前提交
a80fbf9cc2

+ 1 - 1
.env.docker

@@ -11,7 +11,7 @@ CORS_ALLOW_ORIGIN=^https?://(localhost|127\.0\.0\.1)(:[0-9]+)|local.admin.openta
 ###< nelmio/cors-bundle ###
 
 ###> api v1 ###
-API1_BASE_URL=http://api/api
+API1_BASE_URL=http://nginx/
 ###< files management ###
 
 ###> BlackFire configuration ###

+ 1 - 1
config/packages/framework.yaml

@@ -36,5 +36,5 @@ framework:
                 base_uri: '%env(MOBYT_API_BASE_URI)%'
                 headers:
                     Content-Type: 'application/json'
-            api_client:
+            api1_client:
                 base_uri: '%env(API1_BASE_URL)%'

+ 3 - 16
src/DataProvider/Core/DownloadRequestDataProvider.php

@@ -10,7 +10,6 @@ use App\Enum\Core\FileStatusEnum;
 use App\Repository\Core\FileRepository;
 use App\Service\Storage\Api1Storage;
 use App\Service\Storage\LocalStorage;
-use App\Service\Utils\UrlBuilder;
 use Symfony\Component\HttpFoundation\HeaderUtils;
 use Symfony\Component\HttpFoundation\RedirectResponse;
 use Symfony\Component\HttpFoundation\Response;
@@ -42,25 +41,13 @@ final class DownloadRequestDataProvider implements ItemDataProviderInterface, Re
             throw new \RuntimeException("File " . $id . " has " . $file->getStatus() . " status; abort.");
         }
 
+        // Storage depends on the file's host :
         $storage = $file->getHost() === 'ap2i' ? $this->localStorage : $this->api1Storage;
 
-//        if ($file->getHost() === 'api') {
-//            $headers = [
-//                'x-accessid' => $_REQUEST['AccessId'],
-//                'SFSESSID' => $_REQUEST['SFSESSID'],
-//                'BEARER' => $_REQUEST['BEARER'],
-//                'authorization' => 'BEARER ' . $_REQUEST['BEARER'],
-//            ];
-//
-//            $url = UrlBuilder::concatPath($this->api1BaseUrl, 'files/' . $file->getId() .'/download');
-//
-//            return new RedirectResponse($url, 302, $headers);
-//        }
-
+        // Serves the file :
+        // @see https://symfony.com/doc/current/components/http_foundation.html#serving-files
         $content = $storage->read($file);
-        var_dump($content);
 
-        // @see https://symfony.com/doc/current/components/http_foundation.html#serving-files
         $response = new Response($content);
 
         $response->headers->set('Charset', 'UTF-8');

+ 62 - 0
src/Service/Api1/Api1RequestService.php

@@ -0,0 +1,62 @@
+<?php
+
+namespace App\Service\Api1;
+
+use App\Service\Rest\ApiRequestService;
+use JetBrains\PhpStorm\Pure;
+use Symfony\Component\HttpKernel\Exception\HttpException;
+use Symfony\Component\Security\Core\Authentication\Token\NullToken;
+use Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken;
+use Symfony\Component\Security\Core\Security;
+use Symfony\Contracts\HttpClient\HttpClientInterface;
+use Symfony\Contracts\HttpClient\ResponseInterface;
+
+/**
+ * Service d'appel à l'API opentalent V1
+ */
+class Api1RequestService extends ApiRequestService
+{
+    #[Pure]
+    public function __construct(HttpClientInterface $api1_client, private Security $security)
+    {
+        parent::__construct($api1_client);
+    }
+
+    /** @noinspection PhpPossiblePolymorphicInvocationInspection */
+    public function request(
+        string $method,
+        string $url,
+        array $parameters = [],
+        array $options = []
+    ): ResponseInterface {
+
+        $token = $this->security->getToken();
+        if ($token === null || $token instanceof NullToken || $token->getUser() === null) {
+            throw new HttpException(500, 'Request error : Invalid security token');
+        }
+
+        $headers = [
+            'authorization' => 'BEARER ' . $_REQUEST['BEARER'],
+            'Accept' => '*/*',
+            'Accept-Encoding' => 'gzip, deflate, br',
+            'Content-Type' => 'application/ld+json',
+        ];
+
+        if ($token instanceof SwitchUserToken) {
+            $originalUser = $token->getOriginalToken()->getUser();
+            if ($originalUser === null) {
+                throw new HttpException(500, 'Request error : Switch original user missing');
+            }
+
+            $headers['x-accessid'] = $originalUser->getId();
+            $headers['x-switch-access'] = $token->getUser()->getId();
+        } else {
+            $headers['x-accessid'] = $token->getUser()->getId();
+        }
+
+        $options['headers'] = array_merge($options['headers'] ?? [], $headers);
+
+        return parent::request($method, $url, $parameters, $options);
+    }
+
+}

+ 3 - 3
src/Service/Rest/ApiRequestService.php

@@ -48,7 +48,7 @@ class ApiRequestService implements ApiRequestInterface
         try {
             return $this->get($path, $parameters, $options)->getContent();
         } catch (ClientExceptionInterface | TransportExceptionInterface | RedirectionExceptionInterface | ServerExceptionInterface $e) {
-            throw new HttpException(500, 'Request error : ', $e);
+            throw new HttpException(500, 'Request error : ' . $e->getMessage(), $e);
         }
     }
 
@@ -129,8 +129,8 @@ class ApiRequestService implements ApiRequestInterface
         $url = UrlBuilder::concatParameters($url, $parameters);
         try {
             return $this->client->request($method, $url, $options);
-        } catch (HttpExceptionInterface | TransportExceptionInterface $e) {
-            throw new HttpException(500, 'Request error : ', $e);
+        } catch (TransportExceptionInterface $e) {
+            throw new HttpException(500, 'Request error : ' . $e->getMessage(), $e);
         }
     }
 }

+ 4 - 29
src/Service/Storage/Api1Storage.php

@@ -3,6 +3,7 @@
 namespace App\Service\Storage;
 
 use App\Entity\Core\File;
+use App\Service\Api1\Api1RequestService;
 use App\Service\Utils\UrlBuilder;
 use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
 use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
@@ -16,9 +17,8 @@ use Symfony\Contracts\HttpClient\HttpClientInterface;
 class Api1Storage implements FileStorageInterface
 {
     public function __construct(
-        private HttpClientInterface $api_client
-    )
-    {}
+        private Api1RequestService $api1RequestService
+    ) {}
 
     /**
      * Reads the given file and returns its content as a string
@@ -28,31 +28,6 @@ class Api1Storage implements FileStorageInterface
      */
     public function read(File $file): string
     {
-        $headers = [
-            'x-accessid' => $_REQUEST['AccessId'],
-            'SFSESSID' => $_REQUEST['SFSESSID'],
-            'BEARER' => $_REQUEST['BEARER'],
-            'authorization' => 'BEARER ' . $_REQUEST['BEARER'],
-        ];
-
-        try {
-            $response = $this->api_client->request(
-                'POST',
-                'api/files/' . $file->getId() .'/download',
-                ['headers' => $headers]
-            );
-            $content = $response->getContent();
-        } catch (ClientExceptionInterface $e) {
-            throw new \RuntimeException("File " . $file->getId() . " not found", 0, $e);
-        } catch (ServerExceptionInterface | RedirectionExceptionInterface | TransportExceptionInterface $e) {
-            throw new \RuntimeException("File could not be fetched because of a server error", 0, $e);
-        }
-
-        // When the user isn't well authenticated, the api may redirect to the login page or to the portail
-        if (str_contains($content, "<!DOCTYPE html>") && str_contains($content, "This website is powered by TYPO3")) {
-            throw new \RuntimeException("Permission error");
-        }
-
-        return $content;
+        return $this->api1RequestService->getContent('api/files/' . $file->getId() .'/download');
     }
 }