jsonapi.info.yml | 1 + src/Form/JsonApiSettingsForm.php | 7 ++++--- src/Routing/ReadOnlyModeMethodFilter.php | 9 +++++++-- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/jsonapi.info.yml b/jsonapi.info.yml index f92c925..cdaf8e3 100644 --- a/jsonapi.info.yml +++ b/jsonapi.info.yml @@ -3,6 +3,7 @@ type: module description: Exposes entities as a JSON:API-specification-compliant web API. core: 8.x package: Web services +configure: jsonapi.settings dependencies: - drupal:system (>=8.5.11) - drupal:serialization diff --git a/src/Form/JsonApiSettingsForm.php b/src/Form/JsonApiSettingsForm.php index 8d2f4f9..06ae65e 100644 --- a/src/Form/JsonApiSettingsForm.php +++ b/src/Form/JsonApiSettingsForm.php @@ -34,12 +34,13 @@ class JsonApiSettingsForm extends ConfigFormBase { $form['read_only'] = [ '#type' => 'radios', + '#title' => $this->t('Allowed operations'), '#options' => [ - 'r' => $this->t('Allow only reading JSON:API.'), - 'rw' => $this->t('Allow reading and writing JSON:API.'), + 'r' => $this->t('Accept only JSON:API read operations.'), + 'rw' => $this->t('Accept all JSON:API create, read, update, and delete operations.'), ], '#default_value' => $jsonapi_config->get('read_only') === TRUE ? 'r' : 'rw', - '#description' => $this->t('Warning: When writing is allowed, entities (content items, taxonomy terms, …) can be added, changed, or removed via JSON:API. Read more about securing your site with JSON:API.', [':docs' => 'https://www.drupal.org/docs/8/modules/jsonapi/security-considerations']), + '#description' => $this->t('Warning: If read operations alone cover your needs, you can choose to limit JSON:API to just that to reduce your exposure to potential security vulnerabilities in the adding, changing or removing of entities (content items, taxonomy terms, …) via JSON:API. Learn more about securing your site with JSON:API.', [':docs' => 'https://www.drupal.org/docs/8/modules/jsonapi/security-considerations']), ]; return parent::buildForm($form, $form_state); diff --git a/src/Routing/ReadOnlyModeMethodFilter.php b/src/Routing/ReadOnlyModeMethodFilter.php index 9263cbb..e7664e7 100644 --- a/src/Routing/ReadOnlyModeMethodFilter.php +++ b/src/Routing/ReadOnlyModeMethodFilter.php @@ -54,9 +54,14 @@ class ReadOnlyModeMethodFilter implements FilterInterface { $read_only_methods = ['GET', 'HEAD', 'OPTIONS', 'TRACE']; $all_supported_methods = []; foreach ($collection->all() as $name => $route) { + $supported_methods = $route->getMethods(); + assert(count($supported_methods) > 0, 'JSON:API routes always have a method specified.'); + $is_jsonapi_route = $route->hasDefault(Routes::JSON_API_ROUTE_FLAG_KEY); - $is_read_only_route = !empty(array_diff($route->getMethods(), $read_only_methods)); - if ($is_jsonapi_route && $is_read_only_route) { + $is_read_only_route = empty(array_diff($supported_methods, $read_only_methods)); + + if ($is_jsonapi_route && !$is_read_only_route) { + $all_supported_methods = array_merge($supported_methods, $all_supported_methods); $collection->remove($name); } }