diff --git a/Controller/UploadController.php b/Controller/UploadController.php index 18589565a2904abf74a22d93142a081d9d0a62f7..cfcc654af8381e9bf34b8fd0252329e720935e49 100644 --- a/Controller/UploadController.php +++ b/Controller/UploadController.php @@ -28,8 +28,7 @@ use Symfony\Component\Routing\RouterInterface; */ class UploadController extends Controller { - const CSRF_READ_INTENTION = "uploaded_file_read"; - const CSRF_WRITE_INTENTION = "uploaded_file_write_%s"; + const CSRF_INTENTION = "uploaded_file"; /** * @@ -74,12 +73,7 @@ class UploadController extends Controller isset($data['lastModified']) ? $data['lastModified'] : null ); - $token = $this->generateCsrfToken(self::CSRF_WRITE_INTENTION, $file); - - $parameters = [ - 'id' => $file->getId(), - 'token' => $token - ]; + $parameters = ['id' => $file->getId()]; $deleteUrl = $this->router->generate('file_upload_delete', $parameters); @@ -105,7 +99,7 @@ class UploadController extends Controller */ public function putContentAction(Request $request, UploadedFile $file) { - $this->validateCsrfToken($request, self::CSRF_WRITE_INTENTION, $file); + $this->validateCsrfToken($request); if(null !== $range = $request->headers->get('Content-Range', null)) { $matches = []; @@ -141,10 +135,7 @@ class UploadController extends Controller $this->fileManager->completed($file); - $parameters = [ - 'id' => $file->getId(), - 'token' => $request->query->get('token') - ]; + $parameters = ['id' => $file->getId()]; return $this->createResponse( Response::HTTP_OK, @@ -174,7 +165,7 @@ class UploadController extends Controller */ public function getContentAction(Request $request, UploadedFile $file) { - $this->validateCsrfToken($request, self::CSRF_READ_INTENTION); + $this->validateCsrfToken($request); if(!$file->isValid()) { throw new NotFoundHttpException(); @@ -193,40 +184,21 @@ class UploadController extends Controller */ public function deleteAction(Request $request, UploadedFile $file) { - $this->validateCsrfToken($request, self::CSRF_WRITE_INTENTION, $file); + $this->validateCsrfToken($request); $this->fileManager->delete($file); return $this->createResponse(); } - /** - * - * @param type $intention - * @param UploadedFile $file - * @return string - */ - protected function generateCsrfToken($intention, UploadedFile $file = null) - { - if(null !== $file) { - $intention = sprintf($intention, $file->getId()); - } - return $this->csrfProvider->generateCsrfToken($intention); - } - /** * * @param Request $request - * @param type $intention - * @param UploadedFile $file * @throws HttpException */ - protected function validateCsrfToken(Request $request, $intention, UploadedFile $file = null) + protected function validateCsrfToken(Request $request) { - if(null !== $file) { - $intention = sprintf($intention, $file->getId()); - } - if(!$this->csrfProvider->isCsrfTokenValid($intention, $request->query->get('token', null))) { + if(!$this->csrfProvider->isCsrfTokenValid(self::CSRF_INTENTION, $request->query->get('token', null))) { throw new HttpException(Response::HTTP_FORBIDDEN, 'Invalid CSRF token'); } } diff --git a/Form/Type/FileUploadType.php b/Form/Type/FileUploadType.php index 82fd1ae4b7c36fa7c84292b3647aa4aee59253cf..6539fde11d70ce09e9d7ff8fa91c9410568e3e97 100644 --- a/Form/Type/FileUploadType.php +++ b/Form/Type/FileUploadType.php @@ -53,7 +53,7 @@ class FileUploadType extends AbstractType { $this->router = $router; $this->fileManager = $fileManager; - $this->csrfToken = $csrfProvider->generateCsrfToken(UploadController::CSRF_READ_INTENTION); + $this->csrfToken = $csrfProvider->generateCsrfToken(UploadController::CSRF_INTENTION); $this->maxChunkSize = $maxChunkSize; } @@ -74,7 +74,7 @@ class FileUploadType extends AbstractType $this->buildWidgetView($view, $form, $options); $view->vars['widget_attr']['data-create-url'] = $this->router->generate('file_upload_create'); - $view->vars['csrfToken'] = $this->csrfToken; + $view->vars['csrf_token'] = $this->csrfToken; $view->vars['multiple'] = $options['multiple']; if($options['max_chunk_size'] > 0) { $view->vars['widget_attr']['data-max-chunk-size'] = $options['max_chunk_size']; diff --git a/Resources/js/widget/file_upload.js b/Resources/js/widget/file_upload.js index 0b7ee4c46bb0163b803779ba548fdab911eb7657..dc68e3f79c1069dab2f2bea78e2e8a35f7556ee2 100644 --- a/Resources/js/widget/file_upload.js +++ b/Resources/js/widget/file_upload.js @@ -32,11 +32,13 @@ $entries = $this.find('.fileinput-entries'), createUrl = options.createUrl, uploadPrototype = options.uploadPrototype, - downloadPrototype = options.downloadPrototype; + downloadPrototype = options.downloadPrototype, + csrfQuery = '?token=' + options.csrfToken; delete options.createUrl; delete options.uploadPrototype; delete options.downloadPrototype; + delete options.csrfToken; if(options.acceptFileTypes) { options.acceptFileTypes = new RegExp('^' + options.acceptFileTypes + '$'); @@ -95,10 +97,10 @@ } else { row.find('.name a') .text(file.name) - .prop('href', file.url); row.find('button.delete') + .prop('href', file.url + csrfQuery); .attr('data-type', file.delete_type) - .attr('data-url', file.delete_url); + .attr('data-url', file.delete_url + csrfQuery); row.find('input:hidden') .val(file.id); } @@ -114,7 +116,8 @@ { file: { name: file.name, size: file.size, type: file.type, lastModified: file.lastModified } }, function(response) { if(response.status == 201) { - data.url = response.put_url; + file.icon = response.icon; + data.url = response.put_url + csrfQuery; data.delete_url = response.delete_url; data.delete_type = response.delete_type; data.jqXHR = $this.fileupload('send', data); @@ -144,7 +147,7 @@ )).bind({ fileuploadfailed: function (e, data) { if(data.delete_url) { - $.ajax(data.delete_url, { type: data.delete_type }); + $.ajax(data.delete_url + csrfQuery, { type: data.delete_type }); } }, fileuploadadded: updateDisplay, diff --git a/Resources/views/Form/file_upload.html.twig b/Resources/views/Form/file_upload.html.twig index dcfea721d10a5a7f957f2708476a6810410e4417..c4faca4a5409bfc0cd39135ea45c9b4742075306 100644 --- a/Resources/views/Form/file_upload.html.twig +++ b/Resources/views/Form/file_upload.html.twig @@ -18,7 +18,7 @@ <div class="template-download fileinput-entry"> <input type="hidden" name="{{ full_name }}{% if multiple %}[]{% endif %}" value="{{ file.id|default }}"/> <span class="name"> - <a{% if file %} href="{{ path('file_upload_get_content', {id: file.id, token: csrfToken}) }}"{% endif %}>{{ file.originalFilename|default }}</a> + <a{% if file %} href="{{ path('file_upload_get_content', {id: file.id, token: csrf_token}) }}"{% endif %}>{{ file.originalFilename|default }}</a> </span> (<span class="size"> {{- file.size|default -}} @@ -34,6 +34,7 @@ <div id="{{ id }}" class="form-control fileinput-{{ multiple ? "multiple" : "single" }}" {{ block('widget_container_attributes') }} {{ block('widget_only_attributes') }} data-download-prototype="{{ block('file_upload_entry_prototype')|e }}" data-upload-prototype="{{ block('file_upload_progress_prototype')|e }}" + data-csrf-token="{{ csrf_token }}" {% if disabled %}data-disabled="disabled"{% endif -%} {% if read_only %}data-readonly="readonly"{% endif -%} >