From a8d3f780cce04d059d05ebaa590bb1a80e6d67f8 Mon Sep 17 00:00:00 2001
From: Alex Pott <alex.a.pott@googlemail.com>
Date: Mon, 20 Sep 2021 14:21:36 +0100
Subject: [PATCH] Issue #3214675 by el7cosmos, bbrala, hehongbo, larowlan,
 alexpott: JSON:API Cannot upload files to public file root (Gets 422
 Unprocessable Entity)

---
 .../TemporaryJsonapiFileFieldUploader.php     |  6 +++++-
 .../tests/src/Functional/FileUploadTest.php   | 21 +++++++++++++++++++
 2 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/core/modules/jsonapi/src/Controller/TemporaryJsonapiFileFieldUploader.php b/core/modules/jsonapi/src/Controller/TemporaryJsonapiFileFieldUploader.php
index 979c05cb8594..6682bb3a6f8e 100644
--- a/core/modules/jsonapi/src/Controller/TemporaryJsonapiFileFieldUploader.php
+++ b/core/modules/jsonapi/src/Controller/TemporaryJsonapiFileFieldUploader.php
@@ -159,7 +159,8 @@ public function __construct(LoggerInterface $logger, FileSystemInterface $file_s
    */
   public function handleFileUploadForField(FieldDefinitionInterface $field_definition, $filename, AccountInterface $owner) {
     assert(is_a($field_definition->getClass(), FileFieldItemList::class, TRUE));
-    $destination = $this->getUploadLocation($field_definition->getSettings());
+    $settings = $field_definition->getSettings();
+    $destination = $this->getUploadLocation($settings);
 
     // Check the destination file path is writable.
     if (!$this->fileSystem->prepareDirectory($destination, FileSystemInterface::CREATE_DIRECTORY)) {
@@ -172,6 +173,9 @@ public function handleFileUploadForField(FieldDefinitionInterface $field_definit
 
     // Create the file.
     $file_uri = "{$destination}/{$prepared_filename}";
+    if ($destination === $settings['uri_scheme'] . '://') {
+      $file_uri = "{$destination}{$prepared_filename}";
+    }
 
     $temp_file_path = $this->streamUploadData();
 
diff --git a/core/modules/jsonapi/tests/src/Functional/FileUploadTest.php b/core/modules/jsonapi/tests/src/Functional/FileUploadTest.php
index bbce0675d6e0..5627ae8a4d1e 100644
--- a/core/modules/jsonapi/tests/src/Functional/FileUploadTest.php
+++ b/core/modules/jsonapi/tests/src/Functional/FileUploadTest.php
@@ -740,6 +740,27 @@ public function testFileUploadNoExtensionSetting() {
     $this->assertFileExists('public://foobar/example.txt');
   }
 
+  /**
+   * Tests using the file upload POST route no directory configured.
+   */
+  public function testFileUploadNoDirectorySetting() {
+    $this->setUpAuthorization('POST');
+    $this->config('jsonapi.settings')->set('read_only', FALSE)->save(TRUE);
+
+    $uri = Url::fromUri('base:' . static::$postUri);
+
+    $this->field->setSetting('file_directory', '')
+      ->save();
+
+    $response = $this->fileRequest($uri, $this->testFileData, ['Content-Disposition' => 'filename="example.txt"']);
+    $expected = $this->getExpectedDocument(1, 'example.txt', TRUE);
+    $expected['data']['attributes']['uri']['value'] = 'public://example.txt';
+    $expected['data']['attributes']['uri']['url'] = base_path() . $this->siteDirectory . '/files/example.txt';
+
+    $this->assertResponseData($expected, $response);
+    $this->assertFileExists('public://example.txt');
+  }
+
   /**
    * {@inheritdoc}
    */
-- 
GitLab