src/Routing/ReadOnlyModeMethodFilter.php | 9 ++++++--- tests/src/Functional/FileUploadTest.php | 2 ++ tests/src/Functional/ResourceTestBase.php | 3 +++ tests/src/Functional/UserTest.php | 2 ++ 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/Routing/ReadOnlyModeMethodFilter.php b/src/Routing/ReadOnlyModeMethodFilter.php index f12920a..b77cb75 100644 --- a/src/Routing/ReadOnlyModeMethodFilter.php +++ b/src/Routing/ReadOnlyModeMethodFilter.php @@ -45,6 +45,11 @@ class ReadOnlyModeMethodFilter implements FilterInterface { * {@inheritdoc} */ public function filter(RouteCollection $collection, Request $request) { + $all_supported_methods = []; + foreach ($collection->all() as $name => $route) { + $all_supported_methods = array_merge($all_supported_methods, $route->getMethods()); + } + $collection = $this->inner->filter($collection, $request); if (!$this->readOnlyModeIsEnabled) { @@ -52,7 +57,6 @@ class ReadOnlyModeMethodFilter implements FilterInterface { } $read_only_methods = ['GET', 'HEAD', 'OPTIONS', 'TRACE']; - $all_supported_methods = []; foreach ($collection->all() as $name => $route) { if (!$route->hasDefault(Routes::JSON_API_ROUTE_FLAG_KEY)) { continue; @@ -62,14 +66,13 @@ class ReadOnlyModeMethodFilter implements FilterInterface { assert(count($supported_methods) > 0, 'JSON:API routes always have a method specified.'); $is_read_only_route = empty(array_diff($supported_methods, $read_only_methods)); if (!$is_read_only_route) { - $all_supported_methods = array_merge($supported_methods, $all_supported_methods); $collection->remove($name); } } if (count($collection)) { return $collection; } - throw new MethodNotAllowedHttpException(array_unique($all_supported_methods), sprintf("JSON:API's read-only mode is enabled. Site administrators can enable writes at %s.", Url::fromRoute('jsonapi.settings')->setAbsolute()->toString(TRUE)->getGeneratedUrl())); + throw new MethodNotAllowedHttpException(array_intersect($all_supported_methods, $read_only_methods), sprintf("JSON:API's read-only mode is enabled. Site administrators can enable writes at %s.", Url::fromRoute('jsonapi.settings')->setAbsolute()->toString(TRUE)->getGeneratedUrl())); } } diff --git a/tests/src/Functional/FileUploadTest.php b/tests/src/Functional/FileUploadTest.php index 0c2a336..afbe9e2 100644 --- a/tests/src/Functional/FileUploadTest.php +++ b/tests/src/Functional/FileUploadTest.php @@ -207,6 +207,7 @@ class FileUploadTest extends ResourceTestBase { // DX: 405 when read-only mode is enabled. $response = $this->fileRequest($uri, $this->testFileData); $this->assertResourceErrorResponse(405, sprintf("JSON:API's read-only mode is enabled. Site administrators can enable writes at %s.", Url::fromUri('base:/admin/config/services/jsonapi')->setAbsolute()->toString(TRUE)->getGeneratedUrl()), $uri, $response); + $this->assertSame(['GET'], $response->getHeader('Allow')); $this->config('jsonapi.settings')->set('read_only', FALSE)->save(TRUE); @@ -284,6 +285,7 @@ class FileUploadTest extends ResourceTestBase { // DX: 405 when read-only mode is enabled. $response = $this->fileRequest($uri, $this->testFileData); $this->assertResourceErrorResponse(405, sprintf("JSON:API's read-only mode is enabled. Site administrators can enable writes at %s.", Url::fromUri('base:/admin/config/services/jsonapi')->setAbsolute()->toString(TRUE)->getGeneratedUrl()), $uri, $response); + $this->assertSame(['GET'], $response->getHeader('Allow')); $this->config('jsonapi.settings')->set('read_only', FALSE)->save(TRUE); diff --git a/tests/src/Functional/ResourceTestBase.php b/tests/src/Functional/ResourceTestBase.php index c06b67f..3670bef 100644 --- a/tests/src/Functional/ResourceTestBase.php +++ b/tests/src/Functional/ResourceTestBase.php @@ -1902,6 +1902,7 @@ abstract class ResourceTestBase extends BrowserTestBase { // DX: 405 when read-only mode is enabled. $response = $this->request('POST', $url, $request_options); $this->assertResourceErrorResponse(405, sprintf("JSON:API's read-only mode is enabled. Site administrators can enable writes at %s.", Url::fromUri('base:/admin/config/services/jsonapi')->setAbsolute()->toString(TRUE)->getGeneratedUrl()), $url, $response); + $this->assertSame(['GET'], $response->getHeader('Allow')); $this->config('jsonapi.settings')->set('read_only', FALSE)->save(TRUE); @@ -2119,6 +2120,7 @@ abstract class ResourceTestBase extends BrowserTestBase { // DX: 405 when read-only mode is enabled. $response = $this->request('PATCH', $url, $request_options); $this->assertResourceErrorResponse(405, sprintf("JSON:API's read-only mode is enabled. Site administrators can enable writes at %s.", Url::fromUri('base:/admin/config/services/jsonapi')->setAbsolute()->toString(TRUE)->getGeneratedUrl()), $url, $response); + $this->assertSame(['GET'], $response->getHeader('Allow')); $this->config('jsonapi.settings')->set('read_only', FALSE)->save(TRUE); @@ -2412,6 +2414,7 @@ abstract class ResourceTestBase extends BrowserTestBase { // DX: 405 when read-only mode is enabled. $response = $this->request('DELETE', $url, $request_options); $this->assertResourceErrorResponse(405, sprintf("JSON:API's read-only mode is enabled. Site administrators can enable writes at %s.", Url::fromUri('base:/admin/config/services/jsonapi')->setAbsolute()->toString(TRUE)->getGeneratedUrl()), $url, $response); + $this->assertSame(['GET'], $response->getHeader('Allow')); $this->config('jsonapi.settings')->set('read_only', FALSE)->save(TRUE); diff --git a/tests/src/Functional/UserTest.php b/tests/src/Functional/UserTest.php index 7b96783..94d3d5a 100644 --- a/tests/src/Functional/UserTest.php +++ b/tests/src/Functional/UserTest.php @@ -225,6 +225,7 @@ class UserTest extends ResourceTestBase { // DX: 405 when read-only mode is enabled. $response = $this->request('PATCH', $url, $request_options); $this->assertResourceErrorResponse(405, sprintf("JSON:API's read-only mode is enabled. Site administrators can enable writes at %s.", Url::fromUri('base:/admin/config/services/jsonapi')->setAbsolute()->toString(TRUE)->getGeneratedUrl()), $url, $response); + $this->assertSame(['GET'], $response->getHeader('Allow')); $this->config('jsonapi.settings')->set('read_only', FALSE)->save(TRUE); @@ -340,6 +341,7 @@ class UserTest extends ResourceTestBase { // DX: 405 when read-only mode is enabled. $response = $this->request('PATCH', $url, $request_options); $this->assertResourceErrorResponse(405, sprintf("JSON:API's read-only mode is enabled. Site administrators can enable writes at %s.", Url::fromUri('base:/admin/config/services/jsonapi')->setAbsolute()->toString(TRUE)->getGeneratedUrl()), $url, $response); + $this->assertSame(['GET'], $response->getHeader('Allow')); $this->config('jsonapi.settings')->set('read_only', FALSE)->save(TRUE);