diff --git a/composer.json b/composer.json index 10b6b7b0873108ded5574a00aad5f6d75941f52e..aafbec475e44d92c5ff2d3ee8255240436e0f34a 100644 --- a/composer.json +++ b/composer.json @@ -39,6 +39,7 @@ "symfony/string": "5.3.*", "symfony/translation": "5.3.*", "symfony/twig-bundle": "5.3.*", + "symfony/uid": "5.3.*", "symfony/validator": "5.3.*", "symfony/web-link": "5.3.*", "symfony/webpack-encore-bundle": "^1.13", @@ -46,7 +47,8 @@ "symfonycasts/reset-password-bundle": "^1.11", "symfonycasts/verify-email-bundle": "^1.6", "twig/extra-bundle": "^2.12|^3.0", - "twig/twig": "^2.12|^3.0" + "twig/twig": "^2.12|^3.0", + "ext-curl": "*" }, "require-dev": { "dama/doctrine-test-bundle": "^6.7", diff --git a/composer.lock b/composer.lock index ed521583bca8c3a43ed66ca89c1eda64bf925c51..6ed2451fdcd5c35b068bcc0a4805785b42febf1d 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "5cd7753539e87c732ac326302ed3425f", + "content-hash": "c9f90e72255df1e77347e1bd4958fbb4", "packages": [ { "name": "composer/package-versions-deprecated", @@ -5524,6 +5524,85 @@ ], "time": "2021-05-21T13:25:03+00:00" }, + { + "name": "symfony/polyfill-uuid", + "version": "v1.23.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-uuid.git", + "reference": "9165effa2eb8a31bb3fa608df9d529920d21ddd9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-uuid/zipball/9165effa2eb8a31bb3fa608df9d529920d21ddd9", + "reference": "9165effa2eb8a31bb3fa608df9d529920d21ddd9", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-uuid": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Uuid\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Grégoire Pineau", + "email": "lyrixx@lyrixx.info" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for uuid functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "uuid" + ], + "support": { + "source": "https://github.com/symfony/polyfill-uuid/tree/v1.23.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-02-19T12:13:01+00:00" + }, { "name": "symfony/process", "version": "v5.3.12", @@ -7123,6 +7202,79 @@ ], "time": "2021-10-28T13:28:41+00:00" }, + { + "name": "symfony/uid", + "version": "v5.3.10", + "source": { + "type": "git", + "url": "https://github.com/symfony/uid.git", + "reference": "183336998e6b28c37ebf04ee18e6359dfb22084d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/uid/zipball/183336998e6b28c37ebf04ee18e6359dfb22084d", + "reference": "183336998e6b28c37ebf04ee18e6359dfb22084d", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-uuid": "^1.15" + }, + "require-dev": { + "symfony/console": "^4.4|^5.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Uid\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Grégoire Pineau", + "email": "lyrixx@lyrixx.info" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to generate and represent UIDs", + "homepage": "https://symfony.com", + "keywords": [ + "UID", + "uuid" + ], + "support": { + "source": "https://github.com/symfony/uid/tree/v5.3.10" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-10-15T16:00:52+00:00" + }, { "name": "symfony/validator", "version": "v5.3.12", diff --git a/src/Controller/CapsuleController.php b/src/Controller/CapsuleController.php index 654522c0261d89df282cb609955aa58382d56c80..eb32e380b0c5ceb883efc014c26dbeaf42cc3d9f 100644 --- a/src/Controller/CapsuleController.php +++ b/src/Controller/CapsuleController.php @@ -5,9 +5,15 @@ namespace App\Controller; use App\Entity\Capsule; use App\Form\CreateCapsuleFormType; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +use Symfony\Component\HttpFoundation\BinaryFileResponse; +use Symfony\Component\HttpFoundation\File\Exception\FileException; +use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException; +use Symfony\Component\HttpFoundation\File\File; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\Uid\Uuid; class CapsuleController extends AbstractController { @@ -34,11 +40,8 @@ class CapsuleController extends AbstractController if ($form->isSubmitted() && $form->isValid()) { $new_date_time = new \DateTime(); $capsule_name = $form->get('name')->getData(); - $sanitized_capsule_name = $this->sanitize($capsule_name); - - $hashed_and_salted_access_link = password_hash($sanitized_capsule_name, PASSWORD_BCRYPT); - $preview_link = 'preview/' . $hashed_and_salted_access_link; - $edition_link = 'edition/' . $hashed_and_salted_access_link; + $preview_link = Uuid::v4(); + $edition_link = $preview_link . '/?p=edit'; $capsule->setName($capsule_name); $capsule->setCreationAuthor($this->getUser()); @@ -51,7 +54,8 @@ class CapsuleController extends AbstractController $entityManager->persist($capsule); $entityManager->flush(); - return $this->redirectToRoute('capsule_list'); +// return $this->redirectToRoute('capsule_list'); + return $this->transferToLegacy($request); } return $this->render('capsule/create.html.twig', [ @@ -59,18 +63,166 @@ class CapsuleController extends AbstractController ]); } - public static function sanitize($string, $force_lowercase = true, $anal = false) + private function transferToLegacy(Request $request): Response { - $strip = array("~", "`", "!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "_", "=", "+", "[", "{", "]", - "}", "\\", "|", ";", ":", "\"", "'", "‘", "’", "“", "”", "–", "—", - "—", "–", ",", "<", ".", ">", "/", "?"); - $clean = trim(str_replace($strip, "", strip_tags($string))); - $clean = preg_replace('/\s+/', "-", $clean); - $clean = ($anal) ? preg_replace("/[^a-zA-Z0-9]/", "", $clean) : $clean; - return ($force_lowercase) ? - (function_exists('mb_strtolower')) ? - mb_strtolower($clean, 'UTF-8') : - strtolower($clean) : - $clean; + $prefix = $this->getParameter('app.legacy_external_prefix'); + $originalController = preg_replace("@^$prefix@", '', $request->getPathInfo()); + $originalQueryString = $request->getQueryString(); + + //@TODO : delete on linux server + // $originalController = str_replace("/", "\\", $originalController); //windows + + $extension = strrchr($originalController, '.'); + if ($extension != '.html' && $extension != '.php' && $extension != false) { + $url = "{$originalController}"; + try { + $mime = $this->getMime($url, $extension); + $response = new BinaryFileResponse($url); + $response->headers->set('Content-Type', $mime ?: 'application/octet-stream'); + return $response; + } catch (FileNotFoundException $e) { + // try normal access by url + } + } + + $separator = ''; + if (!$extension) { + $separator = '/'; + } + $url = "{$this->getParameter('app.legacy_url')}{$originalController}{$separator}?{$originalQueryString}"; + + //open connection + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); + curl_setopt($ch, CURLOPT_HEADER, 0); + curl_setopt($ch, CURLOPT_VERBOSE, 1); + + // logs the connection (optional) + $stderr = fopen("{$this->getParameter('kernel.project_dir')}/log/curl.txt", "w"); + + if ($request->getMethod() == 'POST') { + $postParameters = $request->request->all()['create_capsule_form']; + + error_log(print_r($postParameters, true)); + + // upload file to transfer + if (isset($_FILES['fileToUpload'])) { + $data = array( + 'fileToUpload' => curl_file_create( + $_FILES['fileToUpload']['tmp_name'], + $_FILES['fileToUpload']['type'], + $_FILES['fileToUpload']['name'] + ) + ); + + $postParameters = array_merge($postParameters, $data); + curl_setopt($ch, CURLOPT_HEADER, 1); + } + + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $postParameters); + } + + curl_setopt($ch, CURLOPT_COOKIESESSION, 0); + curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookies.txt'); + curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookies.txt'); + + //execute post + $result = curl_exec($ch); + $contentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE); + + if ($result === false) { + $error_message = "Erreur - Page non trouvée : " . + curl_error($ch) . + ' - ' . curl_errno($ch); + curl_close($ch); + throw new NotFoundHttpException($error_message); + } + curl_close($ch); + + $response = new Response($result); + $response->headers->set('Content-Type', $contentType); + return $response; + } + + private function getMime($filename, $extension): ?string + { + $mime_types = [ + 'txt' => 'text/plain', + 'htm' => 'text/html', + 'html' => 'text/html', + 'php' => 'text/html', + 'css' => 'text/css', + 'js' => 'application/javascript', + 'json' => 'application/json', + 'xml' => 'application/xml', + 'swf' => 'application/x-shockwave-flash', + 'flv' => 'video/x-flv', + + // images + 'png' => 'image/png', + 'jpe' => 'image/jpeg', + 'jpeg' => 'image/jpeg', + 'jpg' => 'image/jpeg', + 'gif' => 'image/gif', + 'bmp' => 'image/bmp', + 'ico' => 'image/vnd.microsoft.icon', + 'tiff' => 'image/tiff', + 'tif' => 'image/tiff', + 'svg' => 'image/svg+xml', + 'svgz' => 'image/svg+xml', + + // archives + 'zip' => 'application/zip', + 'rar' => 'application/x-rar-compressed', + 'exe' => 'application/x-msdownload', + 'msi' => 'application/x-msdownload', + 'cab' => 'application/vnd.ms-cab-compressed', + + // audio/video + 'mp3' => 'audio/mpeg', + 'qt' => 'video/quicktime', + 'mov' => 'video/quicktime', + + // adobe + 'pdf' => 'application/pdf', + 'psd' => 'image/vnd.adobe.photoshop', + 'ai' => 'application/postscript', + 'eps' => 'application/postscript', + 'ps' => 'application/postscript', + + // ms office + 'doc' => 'application/msword', + 'rtf' => 'application/rtf', + 'xls' => 'application/vnd.ms-excel', + 'ppt' => 'application/vnd.ms-powerpoint', + 'docx' => 'application/msword', + 'xlsx' => 'application/vnd.ms-excel', + 'pptx' => 'application/vnd.ms-powerpoint', + + // open office + 'odt' => 'application/vnd.oasis.opendocument.text', + 'ods' => 'application/vnd.oasis.opendocument.spreadsheet' + ]; + + if (null === $filename) { + throw new \InvalidArgumentException('File cannot be null.'); + } + + $extension_without_dot = strtolower(str_replace('.', '', $extension)); + + if (array_key_exists($extension_without_dot, $mime_types)) { + return $mime_types[$extension_without_dot]; + } + + $file = new File((string) $filename, true); + + if (!$file->isReadable()) { + throw new FileException('File must be readable.'); + } + + return $file->getMimeType(); } }