From d1354342deb40f8a0d844d6353f97bcb2fb9e3d3 Mon Sep 17 00:00:00 2001 From: James Tranovich Date: Tue, 13 Aug 2024 10:52:18 -0700 Subject: [PATCH 01/22] enable JSON:API --- web/config/sync/core.extension.yml | 2 ++ web/config/sync/jsonapi.settings.yml | 6 ++++++ 2 files changed, 8 insertions(+) create mode 100644 web/config/sync/jsonapi.settings.yml diff --git a/web/config/sync/core.extension.yml b/web/config/sync/core.extension.yml index 492e1ba3a..d10e5b331 100644 --- a/web/config/sync/core.extension.yml +++ b/web/config/sync/core.extension.yml @@ -25,6 +25,7 @@ module: help: 0 image: 0 js_cookie: 0 + jsonapi: 0 language: 0 layout_builder: 0 layout_discovery: 0 @@ -44,6 +45,7 @@ module: path_alias: 0 phone_number: 0 scheduler: 0 + serialization: 0 single_content_sync: 0 system: 0 taxonomy: 0 diff --git a/web/config/sync/jsonapi.settings.yml b/web/config/sync/jsonapi.settings.yml new file mode 100644 index 000000000..ebaf9eb25 --- /dev/null +++ b/web/config/sync/jsonapi.settings.yml @@ -0,0 +1,6 @@ +_core: + default_config_hash: bbhVQEgCMWzCNQ9nBMR-PZeax3Tkujtue1HA7CE5574 +read_only: false +maintenance_header_retry_seconds: + min: 5 + max: 10 From 3d1710b739b6f03f9924a65a564aed1ca97dea44 Mon Sep 17 00:00:00 2001 From: James Tranovich Date: Tue, 13 Aug 2024 11:41:58 -0700 Subject: [PATCH 02/22] enable JSON:API extras --- composer.json | 1 + composer.lock | 173 +++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 172 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 206435c03..323b18cfa 100644 --- a/composer.json +++ b/composer.json @@ -24,6 +24,7 @@ "drupal/core-composer-scaffold": "^10.3", "drupal/core-project-message": "^10.3", "drupal/core-recommended": "^10.3", + "drupal/jsonapi_extras": "^3.25", "drupal/key_asymmetric": "^1.1", "drupal/log_stdout": "^1.5", "drupal/metatag": "^2.0", diff --git a/composer.lock b/composer.lock index 7838599f4..6536b95d7 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": "e1f83ea8018ba4e42f0ba2fdb9ae3fed", + "content-hash": "cb9c49253a4d1c4fe2d262ea3487566c", "packages": [ { "name": "asm89/stack-cors", @@ -2241,6 +2241,64 @@ "source": "https://git.drupalcode.org/project/js_cookie" } }, + { + "name": "drupal/jsonapi_extras", + "version": "3.25.0", + "source": { + "type": "git", + "url": "https://git.drupalcode.org/project/jsonapi_extras.git", + "reference": "8.x-3.25" + }, + "dist": { + "type": "zip", + "url": "https://ftp.drupal.org/files/projects/jsonapi_extras-8.x-3.25.zip", + "reference": "8.x-3.25", + "shasum": "ba557127ca560dbf3fae68f76c7720137857f167" + }, + "require": { + "drupal/core": "^9.2 || ^10", + "e0ipso/shaper": "^1" + }, + "type": "drupal-module", + "extra": { + "drupal": { + "version": "8.x-3.25", + "datestamp": "1717340217", + "security-coverage": { + "status": "covered", + "message": "Covered by Drupal's security advisory policy" + } + } + }, + "notification-url": "https://packages.drupal.org/8/downloads", + "license": [ + "GPL-2.0-or-later" + ], + "authors": [ + { + "name": "Mateu Aguiló Bosch", + "homepage": "https://www.drupal.org/user/3366066", + "email": "mateu.aguilo.bosch@gmail.com" + }, + { + "name": "Martin Kolar", + "homepage": "https://www.drupal.org/u/mkolar" + }, + { + "name": "Karel Majzlik", + "homepage": "https://www.drupal.org/u/karlos007" + }, + { + "name": "Björn Brala", + "homepage": "https://www.drupal.org/u/bbrala" + } + ], + "description": "JSON:API Extras provides a means to override and provide limited configurations to the default zero-configuration implementation provided by the JSON:API module.", + "homepage": "https://www.drupal.org/project/jsonapi_extras", + "support": { + "source": "https://git.drupalcode.org/project/jsonapi_extras" + } + }, { "name": "drupal/key", "version": "1.19.0", @@ -3257,6 +3315,52 @@ ], "time": "2024-05-02T17:20:48+00:00" }, + { + "name": "e0ipso/shaper", + "version": "1.2.4", + "source": { + "type": "git", + "url": "https://github.com/e0ipso/shaper.git", + "reference": "7d73018ec4fe8de9730dfe755067cc02460e1a38" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/e0ipso/shaper/zipball/7d73018ec4fe8de9730dfe755067cc02460e1a38", + "reference": "7d73018ec4fe8de9730dfe755067cc02460e1a38", + "shasum": "" + }, + "require": { + "justinrainbow/json-schema": "^5.2" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.4", + "phpunit/phpcov": "^8.2", + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Shaper\\": "src", + "Shaper\\Tests\\": "tests/src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0" + ], + "authors": [ + { + "name": "Mateu Aguiló Bosch", + "email": "mateu.aguilo.bosch@gmail.com" + } + ], + "description": "Lightweight library to handle in and out transformations in PHP.", + "support": { + "issues": "https://github.com/e0ipso/shaper/issues", + "source": "https://github.com/e0ipso/shaper/tree/1.2.4" + }, + "time": "2021-05-19T09:42:57+00:00" + }, { "name": "egulias/email-validator", "version": "4.0.2", @@ -3886,6 +3990,71 @@ ], "time": "2024-07-18T09:59:12+00:00" }, + { + "name": "justinrainbow/json-schema", + "version": "5.3.0", + "source": { + "type": "git", + "url": "https://github.com/jsonrainbow/json-schema.git", + "reference": "feb2ca6dd1cebdaf1ed60a4c8de2e53ce11c4fd8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/jsonrainbow/json-schema/zipball/feb2ca6dd1cebdaf1ed60a4c8de2e53ce11c4fd8", + "reference": "feb2ca6dd1cebdaf1ed60a4c8de2e53ce11c4fd8", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "~2.2.20||~2.15.1", + "json-schema/json-schema-test-suite": "1.2.0", + "phpunit/phpunit": "^4.8.35" + }, + "bin": [ + "bin/validate-json" + ], + "type": "library", + "autoload": { + "psr-4": { + "JsonSchema\\": "src/JsonSchema/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bruno Prieto Reis", + "email": "bruno.p.reis@gmail.com" + }, + { + "name": "Justin Rainbow", + "email": "justin.rainbow@gmail.com" + }, + { + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" + }, + { + "name": "Robert Schönthal", + "email": "seroscho@googlemail.com" + } + ], + "description": "A library to validate a json schema.", + "homepage": "https://github.com/justinrainbow/json-schema", + "keywords": [ + "json", + "schema" + ], + "support": { + "issues": "https://github.com/jsonrainbow/json-schema/issues", + "source": "https://github.com/jsonrainbow/json-schema/tree/5.3.0" + }, + "time": "2024-07-06T21:00:26+00:00" + }, { "name": "league/container", "version": "4.2.2", @@ -10740,5 +10909,5 @@ "prefer-lowest": false, "platform": [], "platform-dev": [], - "plugin-api-version": "2.2.0" + "plugin-api-version": "2.6.0" } From 46a36551ebcf71dc7cbc94e8339f7e1957ee6903 Mon Sep 17 00:00:00 2001 From: James Tranovich Date: Wed, 14 Aug 2024 12:19:24 -0700 Subject: [PATCH 03/22] JSON:API disable by default, finally --- web/config/sync/core.extension.yml | 2 ++ web/config/sync/jsonapi_extras.settings.yml | 6 ++++++ 2 files changed, 8 insertions(+) create mode 100644 web/config/sync/jsonapi_extras.settings.yml diff --git a/web/config/sync/core.extension.yml b/web/config/sync/core.extension.yml index d10e5b331..72255dee3 100644 --- a/web/config/sync/core.extension.yml +++ b/web/config/sync/core.extension.yml @@ -26,6 +26,8 @@ module: image: 0 js_cookie: 0 jsonapi: 0 + jsonapi_defaults: 0 + jsonapi_extras: 0 language: 0 layout_builder: 0 layout_discovery: 0 diff --git a/web/config/sync/jsonapi_extras.settings.yml b/web/config/sync/jsonapi_extras.settings.yml new file mode 100644 index 000000000..df6aab432 --- /dev/null +++ b/web/config/sync/jsonapi_extras.settings.yml @@ -0,0 +1,6 @@ +_core: + default_config_hash: 4_ifqxmFEAYSrGFkA63fLBYAWO-Fz9ACp9qVjkxPghg +path_prefix: jsonapi +include_count: false +default_disabled: true +validate_configuration_integrity: true From a33674601ad09d2115fda30a447c1da0c9f4dfb8 Mon Sep 17 00:00:00 2001 From: James Tranovich Date: Wed, 21 Aug 2024 15:54:51 -0700 Subject: [PATCH 04/22] add WFO PDF upload content type --- ...itylabel.settings.node.wfo_pdf_uploads.yml | 9 ++ ..._override.node.wfo_pdf_uploads.promote.yml | 22 +++++ ...d_override.node.wfo_pdf_uploads.status.yml | 22 +++++ ...ld_override.node.wfo_pdf_uploads.title.yml | 18 ++++ ...m_display.node.wfo_pdf_uploads.default.yml | 90 +++++++++++++++++++ ...w_display.node.wfo_pdf_uploads.default.yml | 30 +++++++ ...ew_display.node.wfo_pdf_uploads.teaser.yml | 23 +++++ ....node.wfo_pdf_uploads.field_wfo_sitrep.yml | 27 ++++++ .../field.storage.node.field_phone_number.yml | 21 +++++ .../field.storage.node.field_wfo_sitrep.yml | 23 +++++ ....content_settings.node.wfo_pdf_uploads.yml | 11 +++ web/config/sync/node.type.wfo_pdf_uploads.yml | 35 ++++++++ 12 files changed, 331 insertions(+) create mode 100644 web/config/sync/auto_entitylabel.settings.node.wfo_pdf_uploads.yml create mode 100644 web/config/sync/core.base_field_override.node.wfo_pdf_uploads.promote.yml create mode 100644 web/config/sync/core.base_field_override.node.wfo_pdf_uploads.status.yml create mode 100644 web/config/sync/core.base_field_override.node.wfo_pdf_uploads.title.yml create mode 100644 web/config/sync/core.entity_form_display.node.wfo_pdf_uploads.default.yml create mode 100644 web/config/sync/core.entity_view_display.node.wfo_pdf_uploads.default.yml create mode 100644 web/config/sync/core.entity_view_display.node.wfo_pdf_uploads.teaser.yml create mode 100644 web/config/sync/field.field.node.wfo_pdf_uploads.field_wfo_sitrep.yml create mode 100644 web/config/sync/field.storage.node.field_phone_number.yml create mode 100644 web/config/sync/field.storage.node.field_wfo_sitrep.yml create mode 100644 web/config/sync/language.content_settings.node.wfo_pdf_uploads.yml create mode 100644 web/config/sync/node.type.wfo_pdf_uploads.yml diff --git a/web/config/sync/auto_entitylabel.settings.node.wfo_pdf_uploads.yml b/web/config/sync/auto_entitylabel.settings.node.wfo_pdf_uploads.yml new file mode 100644 index 000000000..52f716748 --- /dev/null +++ b/web/config/sync/auto_entitylabel.settings.node.wfo_pdf_uploads.yml @@ -0,0 +1,9 @@ +status: 0 +pattern: '' +escape: false +preserve_titles: false +save: false +chunk: 50 +dependencies: + config: + - node.type.wfo_pdf_uploads diff --git a/web/config/sync/core.base_field_override.node.wfo_pdf_uploads.promote.yml b/web/config/sync/core.base_field_override.node.wfo_pdf_uploads.promote.yml new file mode 100644 index 000000000..c3f4ff01d --- /dev/null +++ b/web/config/sync/core.base_field_override.node.wfo_pdf_uploads.promote.yml @@ -0,0 +1,22 @@ +uuid: 6431aada-45e3-41ed-a433-2099e55ce421 +langcode: en +status: true +dependencies: + config: + - node.type.wfo_pdf_uploads +id: node.wfo_pdf_uploads.promote +field_name: promote +entity_type: node +bundle: wfo_pdf_uploads +label: 'Promoted to front page' +description: '' +required: false +translatable: true +default_value: + - + value: 0 +default_value_callback: '' +settings: + on_label: 'On' + off_label: 'Off' +field_type: boolean diff --git a/web/config/sync/core.base_field_override.node.wfo_pdf_uploads.status.yml b/web/config/sync/core.base_field_override.node.wfo_pdf_uploads.status.yml new file mode 100644 index 000000000..b53272f98 --- /dev/null +++ b/web/config/sync/core.base_field_override.node.wfo_pdf_uploads.status.yml @@ -0,0 +1,22 @@ +uuid: 40065a22-4f5e-4edc-b4b1-7206f364be8b +langcode: en +status: true +dependencies: + config: + - node.type.wfo_pdf_uploads +id: node.wfo_pdf_uploads.status +field_name: status +entity_type: node +bundle: wfo_pdf_uploads +label: Published +description: '' +required: false +translatable: true +default_value: + - + value: 0 +default_value_callback: '' +settings: + on_label: 'On' + off_label: 'Off' +field_type: boolean diff --git a/web/config/sync/core.base_field_override.node.wfo_pdf_uploads.title.yml b/web/config/sync/core.base_field_override.node.wfo_pdf_uploads.title.yml new file mode 100644 index 000000000..ece668120 --- /dev/null +++ b/web/config/sync/core.base_field_override.node.wfo_pdf_uploads.title.yml @@ -0,0 +1,18 @@ +uuid: 05b0cc16-5580-4eb5-a2f4-86c3b253570c +langcode: en +status: true +dependencies: + config: + - node.type.wfo_pdf_uploads +id: node.wfo_pdf_uploads.title +field_name: title +entity_type: node +bundle: wfo_pdf_uploads +label: 'PDF file name' +description: '' +required: true +translatable: true +default_value: { } +default_value_callback: '' +settings: { } +field_type: string diff --git a/web/config/sync/core.entity_form_display.node.wfo_pdf_uploads.default.yml b/web/config/sync/core.entity_form_display.node.wfo_pdf_uploads.default.yml new file mode 100644 index 000000000..4d7b68c98 --- /dev/null +++ b/web/config/sync/core.entity_form_display.node.wfo_pdf_uploads.default.yml @@ -0,0 +1,90 @@ +uuid: 4938c747-dd48-407c-8eb8-7ccb995579de +langcode: en +status: true +dependencies: + config: + - field.field.node.wfo_pdf_uploads.field_wfo_sitrep + - node.type.wfo_pdf_uploads + module: + - content_moderation + - file + - path +id: node.wfo_pdf_uploads.default +targetEntityType: node +bundle: wfo_pdf_uploads +mode: default +content: + created: + type: datetime_timestamp + weight: 10 + region: content + settings: { } + third_party_settings: { } + field_wfo_sitrep: + type: file_generic + weight: 121 + region: content + settings: + progress_indicator: throbber + third_party_settings: { } + langcode: + type: language_select + weight: 2 + region: content + settings: + include_locked: true + third_party_settings: { } + moderation_state: + type: moderation_state_default + weight: 100 + region: content + settings: { } + third_party_settings: { } + path: + type: path + weight: 30 + region: content + settings: { } + third_party_settings: { } + promote: + type: boolean_checkbox + weight: 15 + region: content + settings: + display_label: true + third_party_settings: { } + status: + type: boolean_checkbox + weight: 120 + region: content + settings: + display_label: true + third_party_settings: { } + sticky: + type: boolean_checkbox + weight: 16 + region: content + settings: + display_label: true + third_party_settings: { } + title: + type: string_textfield + weight: -5 + region: content + settings: + size: 60 + placeholder: '' + third_party_settings: { } + uid: + type: entity_reference_autocomplete + weight: 5 + region: content + settings: + match_operator: CONTAINS + match_limit: 10 + size: 60 + placeholder: '' + third_party_settings: { } +hidden: + publish_on: true + unpublish_on: true diff --git a/web/config/sync/core.entity_view_display.node.wfo_pdf_uploads.default.yml b/web/config/sync/core.entity_view_display.node.wfo_pdf_uploads.default.yml new file mode 100644 index 000000000..f36503d82 --- /dev/null +++ b/web/config/sync/core.entity_view_display.node.wfo_pdf_uploads.default.yml @@ -0,0 +1,30 @@ +uuid: fdc6e771-c4ad-4a30-bfdc-1467f0bd71fc +langcode: en +status: true +dependencies: + config: + - field.field.node.wfo_pdf_uploads.field_wfo_sitrep + - node.type.wfo_pdf_uploads + module: + - file + - user +id: node.wfo_pdf_uploads.default +targetEntityType: node +bundle: wfo_pdf_uploads +mode: default +content: + field_wfo_sitrep: + type: file_default + label: above + settings: + use_description_as_link_text: true + third_party_settings: { } + weight: 101 + region: content + links: + settings: { } + third_party_settings: { } + weight: 100 + region: content +hidden: + langcode: true diff --git a/web/config/sync/core.entity_view_display.node.wfo_pdf_uploads.teaser.yml b/web/config/sync/core.entity_view_display.node.wfo_pdf_uploads.teaser.yml new file mode 100644 index 000000000..2540f55db --- /dev/null +++ b/web/config/sync/core.entity_view_display.node.wfo_pdf_uploads.teaser.yml @@ -0,0 +1,23 @@ +uuid: b768913a-4823-4317-b0dd-f39d8cb42eb3 +langcode: en +status: true +dependencies: + config: + - core.entity_view_mode.node.teaser + - field.field.node.wfo_pdf_uploads.field_wfo_sitrep + - node.type.wfo_pdf_uploads + module: + - user +id: node.wfo_pdf_uploads.teaser +targetEntityType: node +bundle: wfo_pdf_uploads +mode: teaser +content: + links: + settings: { } + third_party_settings: { } + weight: 100 + region: content +hidden: + field_wfo_sitrep: true + langcode: true diff --git a/web/config/sync/field.field.node.wfo_pdf_uploads.field_wfo_sitrep.yml b/web/config/sync/field.field.node.wfo_pdf_uploads.field_wfo_sitrep.yml new file mode 100644 index 000000000..472491811 --- /dev/null +++ b/web/config/sync/field.field.node.wfo_pdf_uploads.field_wfo_sitrep.yml @@ -0,0 +1,27 @@ +uuid: 695a1588-0c81-441f-b9a3-e16918fcf741 +langcode: en +status: true +dependencies: + config: + - field.storage.node.field_wfo_sitrep + - node.type.wfo_pdf_uploads + module: + - file +id: node.wfo_pdf_uploads.field_wfo_sitrep +field_name: field_wfo_sitrep +entity_type: node +bundle: wfo_pdf_uploads +label: 'WFO SITREP' +description: '' +required: true +translatable: false +default_value: { } +default_value_callback: '' +settings: + handler: 'default:file' + handler_settings: { } + file_directory: '[date:custom:Y]-[date:custom:m]' + file_extensions: pdf + max_filesize: '2 MB' + description_field: false +field_type: file diff --git a/web/config/sync/field.storage.node.field_phone_number.yml b/web/config/sync/field.storage.node.field_phone_number.yml new file mode 100644 index 000000000..0df338bcb --- /dev/null +++ b/web/config/sync/field.storage.node.field_phone_number.yml @@ -0,0 +1,21 @@ +uuid: a3256b52-a2b6-4acc-a3ad-223a1609a47b +langcode: en +status: true +dependencies: + module: + - node +id: node.field_phone_number +field_name: field_phone_number +entity_type: node +type: string +settings: + max_length: 16 + case_sensitive: false + is_ascii: false +module: core +locked: false +cardinality: 1 +translatable: true +indexes: { } +persist_with_no_fields: false +custom_storage: false diff --git a/web/config/sync/field.storage.node.field_wfo_sitrep.yml b/web/config/sync/field.storage.node.field_wfo_sitrep.yml new file mode 100644 index 000000000..3816257d5 --- /dev/null +++ b/web/config/sync/field.storage.node.field_wfo_sitrep.yml @@ -0,0 +1,23 @@ +uuid: d874d37b-d020-4af2-bf1d-d81bdf9d67a3 +langcode: en +status: true +dependencies: + module: + - file + - node +id: node.field_wfo_sitrep +field_name: field_wfo_sitrep +entity_type: node +type: file +settings: + target_type: file + display_field: false + display_default: false + uri_scheme: public +module: file +locked: false +cardinality: 1 +translatable: true +indexes: { } +persist_with_no_fields: false +custom_storage: false diff --git a/web/config/sync/language.content_settings.node.wfo_pdf_uploads.yml b/web/config/sync/language.content_settings.node.wfo_pdf_uploads.yml new file mode 100644 index 000000000..32e110b46 --- /dev/null +++ b/web/config/sync/language.content_settings.node.wfo_pdf_uploads.yml @@ -0,0 +1,11 @@ +uuid: cff4e6c4-50bd-4898-971e-4666e73af40c +langcode: en +status: true +dependencies: + config: + - node.type.wfo_pdf_uploads +id: node.wfo_pdf_uploads +target_entity_type_id: node +target_bundle: wfo_pdf_uploads +default_langcode: zxx +language_alterable: false diff --git a/web/config/sync/node.type.wfo_pdf_uploads.yml b/web/config/sync/node.type.wfo_pdf_uploads.yml new file mode 100644 index 000000000..89fb08466 --- /dev/null +++ b/web/config/sync/node.type.wfo_pdf_uploads.yml @@ -0,0 +1,35 @@ +uuid: f397b481-36e3-46b3-abdb-b48bee05500d +langcode: en +status: true +dependencies: + module: + - menu_ui + - scheduler + - unique_content_field_validation +third_party_settings: + menu_ui: + available_menus: { } + parent: '' + scheduler: + expand_fieldset: when_required + fields_display_mode: vertical_tab + publish_enable: false + publish_past_date: error + publish_past_date_created: false + publish_required: false + publish_revision: false + publish_touch: false + show_message_after_update: true + unpublish_enable: false + unpublish_required: false + unpublish_revision: false + unique_content_field_validation: + unique: 0 + unique_text: '' +name: 'WFO PDF upload' +type: wfo_pdf_uploads +description: 'PDFs that are produced by a WFO, using the DSS Builder (Google Slides) and applicable to any location within their WCA.' +help: null +new_revision: false +preview_mode: 0 +display_submitted: false From 6c2968edfc8b6d68a672cab8f36491942a9a7dd4 Mon Sep 17 00:00:00 2001 From: James Tranovich Date: Wed, 21 Aug 2024 16:10:57 -0700 Subject: [PATCH 05/22] add uploader user type --- ...system.action.user_add_role_action.uploader.yml | 14 ++++++++++++++ ...tem.action.user_remove_role_action.uploader.yml | 14 ++++++++++++++ web/config/sync/user.role.uploader.yml | 14 ++++++++++++++ 3 files changed, 42 insertions(+) create mode 100644 web/config/sync/system.action.user_add_role_action.uploader.yml create mode 100644 web/config/sync/system.action.user_remove_role_action.uploader.yml create mode 100644 web/config/sync/user.role.uploader.yml diff --git a/web/config/sync/system.action.user_add_role_action.uploader.yml b/web/config/sync/system.action.user_add_role_action.uploader.yml new file mode 100644 index 000000000..16de2974c --- /dev/null +++ b/web/config/sync/system.action.user_add_role_action.uploader.yml @@ -0,0 +1,14 @@ +uuid: ec2ebe67-3920-4e11-8361-f36881e080ab +langcode: en +status: true +dependencies: + config: + - user.role.uploader + module: + - user +id: user_add_role_action.uploader +label: 'Add the uploader role to the selected user(s)' +type: user +plugin: user_add_role_action +configuration: + rid: uploader diff --git a/web/config/sync/system.action.user_remove_role_action.uploader.yml b/web/config/sync/system.action.user_remove_role_action.uploader.yml new file mode 100644 index 000000000..6069ffd8d --- /dev/null +++ b/web/config/sync/system.action.user_remove_role_action.uploader.yml @@ -0,0 +1,14 @@ +uuid: a91480df-db51-449d-ab55-f0f388716fdd +langcode: en +status: true +dependencies: + config: + - user.role.uploader + module: + - user +id: user_remove_role_action.uploader +label: 'Remove the uploader role from the selected user(s)' +type: user +plugin: user_remove_role_action +configuration: + rid: uploader diff --git a/web/config/sync/user.role.uploader.yml b/web/config/sync/user.role.uploader.yml new file mode 100644 index 000000000..ac6aaeffe --- /dev/null +++ b/web/config/sync/user.role.uploader.yml @@ -0,0 +1,14 @@ +uuid: 6749ac3e-fc5f-4ed2-a39f-a8742bb61c31 +langcode: en +status: true +dependencies: + config: + - node.type.wfo_pdf_uploads + module: + - node +id: uploader +label: Uploader +weight: -4 +is_admin: null +permissions: + - 'create wfo_pdf_uploads content' From fc162d6a181e3714a5f064a8c7cf75f93a7f54b0 Mon Sep 17 00:00:00 2001 From: James Tranovich Date: Mon, 26 Aug 2024 11:52:38 -0700 Subject: [PATCH 06/22] expose wfo_pdf_uploads fields selectively --- ...d_override.node.wfo_pdf_uploads.status.yml | 2 +- ..._resource_config.node--wfo_pdf_uploads.yml | 166 ++++++++++++++++++ 2 files changed, 167 insertions(+), 1 deletion(-) create mode 100644 web/config/sync/jsonapi_extras.jsonapi_resource_config.node--wfo_pdf_uploads.yml diff --git a/web/config/sync/core.base_field_override.node.wfo_pdf_uploads.status.yml b/web/config/sync/core.base_field_override.node.wfo_pdf_uploads.status.yml index b53272f98..a48f97236 100644 --- a/web/config/sync/core.base_field_override.node.wfo_pdf_uploads.status.yml +++ b/web/config/sync/core.base_field_override.node.wfo_pdf_uploads.status.yml @@ -14,7 +14,7 @@ required: false translatable: true default_value: - - value: 0 + value: 1 default_value_callback: '' settings: on_label: 'On' diff --git a/web/config/sync/jsonapi_extras.jsonapi_resource_config.node--wfo_pdf_uploads.yml b/web/config/sync/jsonapi_extras.jsonapi_resource_config.node--wfo_pdf_uploads.yml new file mode 100644 index 000000000..0ecf2959f --- /dev/null +++ b/web/config/sync/jsonapi_extras.jsonapi_resource_config.node--wfo_pdf_uploads.yml @@ -0,0 +1,166 @@ +uuid: f88a68e4-ccd8-4759-9773-4934bebae456 +langcode: en +status: true +dependencies: + config: + - node.type.wfo_pdf_uploads + module: + - jsonapi_defaults +third_party_settings: + jsonapi_defaults: + page_limit: 50 +id: node--wfo_pdf_uploads +disabled: false +path: node/wfo_pdf_uploads +resourceType: node--wfo_pdf_uploads +resourceFields: + nid: + disabled: true + fieldName: nid + publicName: nid + enhancer: + id: '' + uuid: + disabled: true + fieldName: uuid + publicName: uuid + enhancer: + id: '' + vid: + disabled: true + fieldName: vid + publicName: vid + enhancer: + id: '' + langcode: + disabled: true + fieldName: langcode + publicName: langcode + enhancer: + id: '' + type: + disabled: true + fieldName: type + publicName: type + enhancer: + id: '' + revision_timestamp: + disabled: true + fieldName: revision_timestamp + publicName: revision_timestamp + enhancer: + id: '' + revision_uid: + disabled: true + fieldName: revision_uid + publicName: revision_uid + enhancer: + id: '' + revision_log: + disabled: true + fieldName: revision_log + publicName: revision_log + enhancer: + id: '' + status: + disabled: true + fieldName: status + publicName: status + enhancer: + id: '' + uid: + disabled: true + fieldName: uid + publicName: uid + enhancer: + id: '' + title: + disabled: false + fieldName: title + publicName: title + enhancer: + id: '' + created: + disabled: true + fieldName: created + publicName: created + enhancer: + id: '' + changed: + disabled: true + fieldName: changed + publicName: changed + enhancer: + id: '' + promote: + disabled: true + fieldName: promote + publicName: promote + enhancer: + id: '' + sticky: + disabled: true + fieldName: sticky + publicName: sticky + enhancer: + id: '' + default_langcode: + disabled: true + fieldName: default_langcode + publicName: default_langcode + enhancer: + id: '' + revision_default: + disabled: true + fieldName: revision_default + publicName: revision_default + enhancer: + id: '' + revision_translation_affected: + disabled: true + fieldName: revision_translation_affected + publicName: revision_translation_affected + enhancer: + id: '' + moderation_state: + disabled: true + fieldName: moderation_state + publicName: moderation_state + enhancer: + id: '' + metatag: + disabled: true + fieldName: metatag + publicName: metatag + enhancer: + id: '' + path: + disabled: true + fieldName: path + publicName: path + enhancer: + id: '' + publish_on: + disabled: true + fieldName: publish_on + publicName: publish_on + enhancer: + id: '' + unpublish_on: + disabled: true + fieldName: unpublish_on + publicName: unpublish_on + enhancer: + id: '' + menu_link: + disabled: true + fieldName: menu_link + publicName: menu_link + enhancer: + id: '' + field_wfo_sitrep: + disabled: false + fieldName: field_wfo_sitrep + publicName: field_wfo_sitrep + enhancer: + id: '' From 12e124a26fca062c61fbe1c577bb7c3548357752 Mon Sep 17 00:00:00 2001 From: James Tranovich Date: Mon, 26 Aug 2024 13:32:16 -0700 Subject: [PATCH 07/22] jsonapi: enable file as well for uploads --- web/config/sync/core.extension.yml | 1 + ...ras.jsonapi_resource_config.file--file.yml | 81 +++++++++++++++++++ web/config/sync/node.type.wfo_pdf_uploads.yml | 2 +- 3 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 web/config/sync/jsonapi_extras.jsonapi_resource_config.file--file.yml diff --git a/web/config/sync/core.extension.yml b/web/config/sync/core.extension.yml index 72255dee3..455c672ad 100644 --- a/web/config/sync/core.extension.yml +++ b/web/config/sync/core.extension.yml @@ -5,6 +5,7 @@ module: address: 0 auto_entitylabel: 0 automated_cron: 0 + basic_auth: 0 big_pipe: 0 block: 0 block_content: 0 diff --git a/web/config/sync/jsonapi_extras.jsonapi_resource_config.file--file.yml b/web/config/sync/jsonapi_extras.jsonapi_resource_config.file--file.yml new file mode 100644 index 000000000..c77181d87 --- /dev/null +++ b/web/config/sync/jsonapi_extras.jsonapi_resource_config.file--file.yml @@ -0,0 +1,81 @@ +uuid: 240f97f0-866b-41e7-ade0-9c661f372554 +langcode: en +status: true +dependencies: + module: + - file + - jsonapi_defaults +third_party_settings: + jsonapi_defaults: + page_limit: 50 +id: file--file +disabled: false +path: file/file +resourceType: file--file +resourceFields: + fid: + disabled: false + fieldName: fid + publicName: fid + enhancer: + id: '' + uuid: + disabled: false + fieldName: uuid + publicName: uuid + enhancer: + id: '' + langcode: + disabled: false + fieldName: langcode + publicName: langcode + enhancer: + id: '' + uid: + disabled: false + fieldName: uid + publicName: uid + enhancer: + id: '' + filename: + disabled: false + fieldName: filename + publicName: filename + enhancer: + id: '' + uri: + disabled: false + fieldName: uri + publicName: uri + enhancer: + id: '' + filemime: + disabled: false + fieldName: filemime + publicName: filemime + enhancer: + id: '' + filesize: + disabled: false + fieldName: filesize + publicName: filesize + enhancer: + id: '' + status: + disabled: false + fieldName: status + publicName: status + enhancer: + id: '' + created: + disabled: false + fieldName: created + publicName: created + enhancer: + id: '' + changed: + disabled: false + fieldName: changed + publicName: changed + enhancer: + id: '' diff --git a/web/config/sync/node.type.wfo_pdf_uploads.yml b/web/config/sync/node.type.wfo_pdf_uploads.yml index 89fb08466..7da061af1 100644 --- a/web/config/sync/node.type.wfo_pdf_uploads.yml +++ b/web/config/sync/node.type.wfo_pdf_uploads.yml @@ -31,5 +31,5 @@ type: wfo_pdf_uploads description: 'PDFs that are produced by a WFO, using the DSS Builder (Google Slides) and applicable to any location within their WCA.' help: null new_revision: false -preview_mode: 0 +preview_mode: 2 display_submitted: false From bb14ee6af64675961d1c679ef1b4652f0768997b Mon Sep 17 00:00:00 2001 From: James Tranovich Date: Mon, 26 Aug 2024 16:06:09 -0700 Subject: [PATCH 08/22] added jsonapi_extras documentation --- docs/dev/contributed-modules.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/dev/contributed-modules.md b/docs/dev/contributed-modules.md index 4e140786b..9529a656f 100644 --- a/docs/dev/contributed-modules.md +++ b/docs/dev/contributed-modules.md @@ -150,3 +150,9 @@ We use this module to get a specific phone number field type, along with validat _Added July 2024_ This module gives us a physical address field type, along with configuration options and validation. Used initially for WFO Information. + +### [`jsonapi_extras`](https://www.drupal.org/project/jsonapi_extras) + +_Added August 2024_ + +We use this module to disable all resource access by default, via the API endpoint. We also use this module to disable certain fields within Drupal content types. From 8b333cde808675b5006c545841221377fdaae37a Mon Sep 17 00:00:00 2001 From: James Tranovich Date: Tue, 27 Aug 2024 09:27:05 -0700 Subject: [PATCH 09/22] added json-api documentation --- docs/dev/contributed-modules.md | 2 +- docs/dev/json-api.md | 65 +++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 docs/dev/json-api.md diff --git a/docs/dev/contributed-modules.md b/docs/dev/contributed-modules.md index 9529a656f..4af8b2769 100644 --- a/docs/dev/contributed-modules.md +++ b/docs/dev/contributed-modules.md @@ -155,4 +155,4 @@ This module gives us a physical address field type, along with configuration opt _Added August 2024_ -We use this module to disable all resource access by default, via the API endpoint. We also use this module to disable certain fields within Drupal content types. +We use this module to disable resource access by default, via the API endpoint. We also use this module to disable certain fields within permitted Drupal content types for the API endpoint. Please see [./json-api.md](the JSON:API documentation) for more information. diff --git a/docs/dev/json-api.md b/docs/dev/json-api.md new file mode 100644 index 000000000..cc5d06e09 --- /dev/null +++ b/docs/dev/json-api.md @@ -0,0 +1,65 @@ +# JSON:API + +## Modules + +We have enabled and configured the core Drupal [`jsonapi`](https://www.drupal.org/docs/core-modules-and-themes/core-modules/jsonapi-module/api-overview) module specifically to allow uploading of WFO daily situation reports, which are produced as PDFs. + +We are also enabling the following core Drupal modules: + +- [`basic_auth`](https://www.drupal.org/docs/8/core/modules/basic_auth/overview) for authentication +- [`jsonapi_extras`](https://www.drupal.org/project/jsonapi_extras) by default, prevent resources (and resource fields) from being accessible via the API +- [`jsonapi_defaults`](https://www.drupal.org/project/jsonapi_defaults) is a submodule of the above which adds defaults to API resource types +- [`serialization`](https://www.drupal.org/docs/8/core/modules/serialization/overview) for JSON support + +## Configuration + +A new content type, `wfo_pdf_upload` was created for WFO daily situation reports. The `field_wfo_sitrep` field holds the PDF file. + +We have configured JSON:API to only display `wfo_pdf_upload`s and `file`s. (The latter is needed because we need to upload the PDF and then link the PDF to the `wfo_pdf_upload`.) Furthermore, `wfo_pdf_upload` is configured to only allow the `title` and `field_wfo_sitrep` fields to be shown or set. `file` is configured to only allow the `uri` field to be shown. + +We have also configured a new user type, `uploader`, which has no permissions except to create new `wfo_pdf_upload`s. + +Because JSON:API follows Drupal entity permissions, JSON:API also respects the user permissions for that entity type. This means that currently `anonymous` users can browse the JSON API, including viewing `file`s and `wfo_pdf_upload`s, because `anonymous` users can `view published content`. (This will change in a later version.) + +# Example + +Uploading a WFO sitrep is a two step process. Here, we use `curl` as an example. We also assume an `uploader` user type is used with the password `uploader` (please do not create this example user for any public site). + +First, we upload the PDF itself to the `wfo_pdf_upload/field_wfo_sitrep` field (note: you can create a blank PDF by using [`imagemagick`](https://imagemagick.org/index.php): `magick xc:none -page Letter test.pdf`): + + curl -sL \ + --user uploader:uploader \ + -H 'Accept: application/vnd.api+json' \ + -H 'Content-Type: application/octet-stream' \ + -H 'Content-Disposition: file; filename="test.pdf"' \ + -d @test.pdf \ + http://localhost:8080/jsonapi/node/wfo_pdf_uploads/field_wfo_sitrep + +The response should be a 201 with JSON information about the newly uploaded file attributes. We want the `id` of the newly uploaded file for the next step. (You can use `jq` and add a pipe: `| jq "data.id"` above to more easily retrieve the resulting `id`.) + +Let's assume the newly created PDF `id` is `9986844e-c190-428a-b152-7c3a03244b71`. + +Second, we create the `wfo_pdf_upload` entity itself and link the PDF `id`: + + curl -sL \ + --user uploader:uploader \ + -H 'Accept: application/vnd.api+json' \ + -H 'Content-Type: application/vnd.api+json' \ + -d '{"data": { + "type": "node--wfo_pdf_uploads", + "attributes": { + "title": "test.pdf" + }, + "relationships": { + "field_wfo_sitrep": { + "data": { + "type": "file--file", + "id": "9986844e-c190-428a-b152-7c3a03244b71" + } + } + } + } + }' \ + http://localhost:8888/jsonapi/node/wfo_pdf_uploads + +The response should also be a 201 with JSON information about the newly created `wfo_pdf_upload` entity. From f9584fa9590a4fa8789fa49e1aaada264be7af42 Mon Sep 17 00:00:00 2001 From: James Tranovich Date: Tue, 27 Aug 2024 09:31:27 -0700 Subject: [PATCH 10/22] tweak documentation and export file field config --- docs/dev/json-api.md | 2 +- ...ras.jsonapi_resource_config.file--file.yml | 20 +++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/dev/json-api.md b/docs/dev/json-api.md index cc5d06e09..92d884d5b 100644 --- a/docs/dev/json-api.md +++ b/docs/dev/json-api.md @@ -60,6 +60,6 @@ Second, we create the `wfo_pdf_upload` entity itself and link the PDF `id`: } } }' \ - http://localhost:8888/jsonapi/node/wfo_pdf_uploads + http://localhost:8080/jsonapi/node/wfo_pdf_uploads The response should also be a 201 with JSON information about the newly created `wfo_pdf_upload` entity. diff --git a/web/config/sync/jsonapi_extras.jsonapi_resource_config.file--file.yml b/web/config/sync/jsonapi_extras.jsonapi_resource_config.file--file.yml index c77181d87..117246e4a 100644 --- a/web/config/sync/jsonapi_extras.jsonapi_resource_config.file--file.yml +++ b/web/config/sync/jsonapi_extras.jsonapi_resource_config.file--file.yml @@ -14,31 +14,31 @@ path: file/file resourceType: file--file resourceFields: fid: - disabled: false + disabled: true fieldName: fid publicName: fid enhancer: id: '' uuid: - disabled: false + disabled: true fieldName: uuid publicName: uuid enhancer: id: '' langcode: - disabled: false + disabled: true fieldName: langcode publicName: langcode enhancer: id: '' uid: - disabled: false + disabled: true fieldName: uid publicName: uid enhancer: id: '' filename: - disabled: false + disabled: true fieldName: filename publicName: filename enhancer: @@ -50,31 +50,31 @@ resourceFields: enhancer: id: '' filemime: - disabled: false + disabled: true fieldName: filemime publicName: filemime enhancer: id: '' filesize: - disabled: false + disabled: true fieldName: filesize publicName: filesize enhancer: id: '' status: - disabled: false + disabled: true fieldName: status publicName: status enhancer: id: '' created: - disabled: false + disabled: true fieldName: created publicName: created enhancer: id: '' changed: - disabled: false + disabled: true fieldName: changed publicName: changed enhancer: From 2bb4070c9fb06159ce3dd9a36fecdc2deab25bfa Mon Sep 17 00:00:00 2001 From: James Tranovich Date: Wed, 28 Aug 2024 11:27:19 -0700 Subject: [PATCH 11/22] apache: block JSON:API GET requests --- .../httpd/user-provided/httpd-block-api-get-requests.conf | 8 ++++++++ docker-compose.yml | 3 +++ docs/dev/json-api.md | 4 +++- 3 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 .bp-config/httpd/user-provided/httpd-block-api-get-requests.conf diff --git a/.bp-config/httpd/user-provided/httpd-block-api-get-requests.conf b/.bp-config/httpd/user-provided/httpd-block-api-get-requests.conf new file mode 100644 index 000000000..09065c527 --- /dev/null +++ b/.bp-config/httpd/user-provided/httpd-block-api-get-requests.conf @@ -0,0 +1,8 @@ +# Enable rewriting so we can block JSON:API GET requests +LoadModule rewrite_module modules/mod_rewrite.so + + + RewriteEngine On + RewriteCond %{REQUEST_METHOD} ^(GET|DELETE|PUT) [NC] + RewriteRule .* - [F,L] + diff --git a/docker-compose.yml b/docker-compose.yml index cf1e9ac2a..10056bad5 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -82,6 +82,9 @@ services: # Map in our test coverage directory so we can have those pretty outputs. - ./.coverage:/coverage + # Map specific apache2 conf settings (optional) + # - ./.bp-config/httpd/user-provided/httpd-block-api-get-requests.conf:/etc/apache2/conf-enabled/httpd-block-api-get-requests.conf + plantuml: build: context: ./ diff --git a/docs/dev/json-api.md b/docs/dev/json-api.md index 92d884d5b..f6e5d7f2d 100644 --- a/docs/dev/json-api.md +++ b/docs/dev/json-api.md @@ -19,7 +19,9 @@ We have configured JSON:API to only display `wfo_pdf_upload`s and `file`s. (The We have also configured a new user type, `uploader`, which has no permissions except to create new `wfo_pdf_upload`s. -Because JSON:API follows Drupal entity permissions, JSON:API also respects the user permissions for that entity type. This means that currently `anonymous` users can browse the JSON API, including viewing `file`s and `wfo_pdf_upload`s, because `anonymous` users can `view published content`. (This will change in a later version.) +Because JSON:API follows Drupal entity permissions, JSON:API also respects the user permissions for that entity type. This means that currently `anonymous` users can browse the JSON API, including viewing `file`s and `wfo_pdf_upload`s, because `anonymous` users can `view published content`. + +Because we do not have an use case for listing resources, we are blocking all `GET` requests for the JSON:API via an [Apache configuration](../../.bp-config/httpd/user-provided/httpd-block-api-get-requests.conf). # Example From fb7136e241643827a5435d236699ced5afedad7a Mon Sep 17 00:00:00 2001 From: James Tranovich Date: Wed, 28 Aug 2024 11:34:55 -0700 Subject: [PATCH 12/22] doc: remove jsonapi_defaults deprecated link --- docs/dev/json-api.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dev/json-api.md b/docs/dev/json-api.md index f6e5d7f2d..c38783159 100644 --- a/docs/dev/json-api.md +++ b/docs/dev/json-api.md @@ -8,7 +8,7 @@ We are also enabling the following core Drupal modules: - [`basic_auth`](https://www.drupal.org/docs/8/core/modules/basic_auth/overview) for authentication - [`jsonapi_extras`](https://www.drupal.org/project/jsonapi_extras) by default, prevent resources (and resource fields) from being accessible via the API -- [`jsonapi_defaults`](https://www.drupal.org/project/jsonapi_defaults) is a submodule of the above which adds defaults to API resource types +- `jsonapi_defaults` is a submodule of the above which adds defaults to API resource types - [`serialization`](https://www.drupal.org/docs/8/core/modules/serialization/overview) for JSON support ## Configuration From 47e8fc7b842f44b8ef5bbd43cefa15ed95ddefce Mon Sep 17 00:00:00 2001 From: James Tranovich Date: Wed, 28 Aug 2024 11:41:25 -0700 Subject: [PATCH 13/22] rename: wfo_pdf_uploads -> wfo_pdf_upload --- docs/dev/json-api.md | 6 +++--- ... => auto_entitylabel.settings.node.wfo_pdf_upload.yml} | 2 +- ...e.base_field_override.node.wfo_pdf_upload.promote.yml} | 6 +++--- ...re.base_field_override.node.wfo_pdf_upload.status.yml} | 6 +++--- ...ore.base_field_override.node.wfo_pdf_upload.title.yml} | 6 +++--- ...e.entity_form_display.node.wfo_pdf_upload.default.yml} | 8 ++++---- ...e.entity_view_display.node.wfo_pdf_upload.default.yml} | 8 ++++---- ...re.entity_view_display.node.wfo_pdf_upload.teaser.yml} | 8 ++++---- ... field.field.node.wfo_pdf_upload.field_wfo_sitrep.yml} | 6 +++--- ...tras.jsonapi_resource_config.node--wfo_pdf_upload.yml} | 8 ++++---- ... => language.content_settings.node.wfo_pdf_upload.yml} | 6 +++--- ...e.wfo_pdf_uploads.yml => node.type.wfo_pdf_upload.yml} | 2 +- web/config/sync/user.role.uploader.yml | 4 ++-- 13 files changed, 38 insertions(+), 38 deletions(-) rename web/config/sync/{auto_entitylabel.settings.node.wfo_pdf_uploads.yml => auto_entitylabel.settings.node.wfo_pdf_upload.yml} (76%) rename web/config/sync/{core.base_field_override.node.wfo_pdf_uploads.promote.yml => core.base_field_override.node.wfo_pdf_upload.promote.yml} (79%) rename web/config/sync/{core.base_field_override.node.wfo_pdf_uploads.status.yml => core.base_field_override.node.wfo_pdf_upload.status.yml} (78%) rename web/config/sync/{core.base_field_override.node.wfo_pdf_uploads.title.yml => core.base_field_override.node.wfo_pdf_upload.title.yml} (76%) rename web/config/sync/{core.entity_form_display.node.wfo_pdf_uploads.default.yml => core.entity_form_display.node.wfo_pdf_upload.default.yml} (92%) rename web/config/sync/{core.entity_view_display.node.wfo_pdf_uploads.default.yml => core.entity_view_display.node.wfo_pdf_upload.default.yml} (76%) rename web/config/sync/{core.entity_view_display.node.wfo_pdf_uploads.teaser.yml => core.entity_view_display.node.wfo_pdf_upload.teaser.yml} (70%) rename web/config/sync/{field.field.node.wfo_pdf_uploads.field_wfo_sitrep.yml => field.field.node.wfo_pdf_upload.field_wfo_sitrep.yml} (84%) rename web/config/sync/{jsonapi_extras.jsonapi_resource_config.node--wfo_pdf_uploads.yml => jsonapi_extras.jsonapi_resource_config.node--wfo_pdf_upload.yml} (96%) rename web/config/sync/{language.content_settings.node.wfo_pdf_uploads.yml => language.content_settings.node.wfo_pdf_upload.yml} (65%) rename web/config/sync/{node.type.wfo_pdf_uploads.yml => node.type.wfo_pdf_upload.yml} (97%) diff --git a/docs/dev/json-api.md b/docs/dev/json-api.md index c38783159..9049a75fa 100644 --- a/docs/dev/json-api.md +++ b/docs/dev/json-api.md @@ -35,7 +35,7 @@ First, we upload the PDF itself to the `wfo_pdf_upload/field_wfo_sitrep` field ( -H 'Content-Type: application/octet-stream' \ -H 'Content-Disposition: file; filename="test.pdf"' \ -d @test.pdf \ - http://localhost:8080/jsonapi/node/wfo_pdf_uploads/field_wfo_sitrep + http://localhost:8080/jsonapi/node/wfo_pdf_upload/field_wfo_sitrep The response should be a 201 with JSON information about the newly uploaded file attributes. We want the `id` of the newly uploaded file for the next step. (You can use `jq` and add a pipe: `| jq "data.id"` above to more easily retrieve the resulting `id`.) @@ -48,7 +48,7 @@ Second, we create the `wfo_pdf_upload` entity itself and link the PDF `id`: -H 'Accept: application/vnd.api+json' \ -H 'Content-Type: application/vnd.api+json' \ -d '{"data": { - "type": "node--wfo_pdf_uploads", + "type": "node--wfo_pdf_upload", "attributes": { "title": "test.pdf" }, @@ -62,6 +62,6 @@ Second, we create the `wfo_pdf_upload` entity itself and link the PDF `id`: } } }' \ - http://localhost:8080/jsonapi/node/wfo_pdf_uploads + http://localhost:8080/jsonapi/node/wfo_pdf_upload The response should also be a 201 with JSON information about the newly created `wfo_pdf_upload` entity. diff --git a/web/config/sync/auto_entitylabel.settings.node.wfo_pdf_uploads.yml b/web/config/sync/auto_entitylabel.settings.node.wfo_pdf_upload.yml similarity index 76% rename from web/config/sync/auto_entitylabel.settings.node.wfo_pdf_uploads.yml rename to web/config/sync/auto_entitylabel.settings.node.wfo_pdf_upload.yml index 52f716748..8f1090cb9 100644 --- a/web/config/sync/auto_entitylabel.settings.node.wfo_pdf_uploads.yml +++ b/web/config/sync/auto_entitylabel.settings.node.wfo_pdf_upload.yml @@ -6,4 +6,4 @@ save: false chunk: 50 dependencies: config: - - node.type.wfo_pdf_uploads + - node.type.wfo_pdf_upload diff --git a/web/config/sync/core.base_field_override.node.wfo_pdf_uploads.promote.yml b/web/config/sync/core.base_field_override.node.wfo_pdf_upload.promote.yml similarity index 79% rename from web/config/sync/core.base_field_override.node.wfo_pdf_uploads.promote.yml rename to web/config/sync/core.base_field_override.node.wfo_pdf_upload.promote.yml index c3f4ff01d..61216eaf9 100644 --- a/web/config/sync/core.base_field_override.node.wfo_pdf_uploads.promote.yml +++ b/web/config/sync/core.base_field_override.node.wfo_pdf_upload.promote.yml @@ -3,11 +3,11 @@ langcode: en status: true dependencies: config: - - node.type.wfo_pdf_uploads -id: node.wfo_pdf_uploads.promote + - node.type.wfo_pdf_upload +id: node.wfo_pdf_upload.promote field_name: promote entity_type: node -bundle: wfo_pdf_uploads +bundle: wfo_pdf_upload label: 'Promoted to front page' description: '' required: false diff --git a/web/config/sync/core.base_field_override.node.wfo_pdf_uploads.status.yml b/web/config/sync/core.base_field_override.node.wfo_pdf_upload.status.yml similarity index 78% rename from web/config/sync/core.base_field_override.node.wfo_pdf_uploads.status.yml rename to web/config/sync/core.base_field_override.node.wfo_pdf_upload.status.yml index a48f97236..09294f0e0 100644 --- a/web/config/sync/core.base_field_override.node.wfo_pdf_uploads.status.yml +++ b/web/config/sync/core.base_field_override.node.wfo_pdf_upload.status.yml @@ -3,11 +3,11 @@ langcode: en status: true dependencies: config: - - node.type.wfo_pdf_uploads -id: node.wfo_pdf_uploads.status + - node.type.wfo_pdf_upload +id: node.wfo_pdf_upload.status field_name: status entity_type: node -bundle: wfo_pdf_uploads +bundle: wfo_pdf_upload label: Published description: '' required: false diff --git a/web/config/sync/core.base_field_override.node.wfo_pdf_uploads.title.yml b/web/config/sync/core.base_field_override.node.wfo_pdf_upload.title.yml similarity index 76% rename from web/config/sync/core.base_field_override.node.wfo_pdf_uploads.title.yml rename to web/config/sync/core.base_field_override.node.wfo_pdf_upload.title.yml index ece668120..e6b485cc6 100644 --- a/web/config/sync/core.base_field_override.node.wfo_pdf_uploads.title.yml +++ b/web/config/sync/core.base_field_override.node.wfo_pdf_upload.title.yml @@ -3,11 +3,11 @@ langcode: en status: true dependencies: config: - - node.type.wfo_pdf_uploads -id: node.wfo_pdf_uploads.title + - node.type.wfo_pdf_upload +id: node.wfo_pdf_upload.title field_name: title entity_type: node -bundle: wfo_pdf_uploads +bundle: wfo_pdf_upload label: 'PDF file name' description: '' required: true diff --git a/web/config/sync/core.entity_form_display.node.wfo_pdf_uploads.default.yml b/web/config/sync/core.entity_form_display.node.wfo_pdf_upload.default.yml similarity index 92% rename from web/config/sync/core.entity_form_display.node.wfo_pdf_uploads.default.yml rename to web/config/sync/core.entity_form_display.node.wfo_pdf_upload.default.yml index 4d7b68c98..0459af2f9 100644 --- a/web/config/sync/core.entity_form_display.node.wfo_pdf_uploads.default.yml +++ b/web/config/sync/core.entity_form_display.node.wfo_pdf_upload.default.yml @@ -3,15 +3,15 @@ langcode: en status: true dependencies: config: - - field.field.node.wfo_pdf_uploads.field_wfo_sitrep - - node.type.wfo_pdf_uploads + - field.field.node.wfo_pdf_upload.field_wfo_sitrep + - node.type.wfo_pdf_upload module: - content_moderation - file - path -id: node.wfo_pdf_uploads.default +id: node.wfo_pdf_upload.default targetEntityType: node -bundle: wfo_pdf_uploads +bundle: wfo_pdf_upload mode: default content: created: diff --git a/web/config/sync/core.entity_view_display.node.wfo_pdf_uploads.default.yml b/web/config/sync/core.entity_view_display.node.wfo_pdf_upload.default.yml similarity index 76% rename from web/config/sync/core.entity_view_display.node.wfo_pdf_uploads.default.yml rename to web/config/sync/core.entity_view_display.node.wfo_pdf_upload.default.yml index f36503d82..ce228a6b6 100644 --- a/web/config/sync/core.entity_view_display.node.wfo_pdf_uploads.default.yml +++ b/web/config/sync/core.entity_view_display.node.wfo_pdf_upload.default.yml @@ -3,14 +3,14 @@ langcode: en status: true dependencies: config: - - field.field.node.wfo_pdf_uploads.field_wfo_sitrep - - node.type.wfo_pdf_uploads + - field.field.node.wfo_pdf_upload.field_wfo_sitrep + - node.type.wfo_pdf_upload module: - file - user -id: node.wfo_pdf_uploads.default +id: node.wfo_pdf_upload.default targetEntityType: node -bundle: wfo_pdf_uploads +bundle: wfo_pdf_upload mode: default content: field_wfo_sitrep: diff --git a/web/config/sync/core.entity_view_display.node.wfo_pdf_uploads.teaser.yml b/web/config/sync/core.entity_view_display.node.wfo_pdf_upload.teaser.yml similarity index 70% rename from web/config/sync/core.entity_view_display.node.wfo_pdf_uploads.teaser.yml rename to web/config/sync/core.entity_view_display.node.wfo_pdf_upload.teaser.yml index 2540f55db..792600fbf 100644 --- a/web/config/sync/core.entity_view_display.node.wfo_pdf_uploads.teaser.yml +++ b/web/config/sync/core.entity_view_display.node.wfo_pdf_upload.teaser.yml @@ -4,13 +4,13 @@ status: true dependencies: config: - core.entity_view_mode.node.teaser - - field.field.node.wfo_pdf_uploads.field_wfo_sitrep - - node.type.wfo_pdf_uploads + - field.field.node.wfo_pdf_upload.field_wfo_sitrep + - node.type.wfo_pdf_upload module: - user -id: node.wfo_pdf_uploads.teaser +id: node.wfo_pdf_upload.teaser targetEntityType: node -bundle: wfo_pdf_uploads +bundle: wfo_pdf_upload mode: teaser content: links: diff --git a/web/config/sync/field.field.node.wfo_pdf_uploads.field_wfo_sitrep.yml b/web/config/sync/field.field.node.wfo_pdf_upload.field_wfo_sitrep.yml similarity index 84% rename from web/config/sync/field.field.node.wfo_pdf_uploads.field_wfo_sitrep.yml rename to web/config/sync/field.field.node.wfo_pdf_upload.field_wfo_sitrep.yml index 472491811..a39558b3c 100644 --- a/web/config/sync/field.field.node.wfo_pdf_uploads.field_wfo_sitrep.yml +++ b/web/config/sync/field.field.node.wfo_pdf_upload.field_wfo_sitrep.yml @@ -4,13 +4,13 @@ status: true dependencies: config: - field.storage.node.field_wfo_sitrep - - node.type.wfo_pdf_uploads + - node.type.wfo_pdf_upload module: - file -id: node.wfo_pdf_uploads.field_wfo_sitrep +id: node.wfo_pdf_upload.field_wfo_sitrep field_name: field_wfo_sitrep entity_type: node -bundle: wfo_pdf_uploads +bundle: wfo_pdf_upload label: 'WFO SITREP' description: '' required: true diff --git a/web/config/sync/jsonapi_extras.jsonapi_resource_config.node--wfo_pdf_uploads.yml b/web/config/sync/jsonapi_extras.jsonapi_resource_config.node--wfo_pdf_upload.yml similarity index 96% rename from web/config/sync/jsonapi_extras.jsonapi_resource_config.node--wfo_pdf_uploads.yml rename to web/config/sync/jsonapi_extras.jsonapi_resource_config.node--wfo_pdf_upload.yml index 0ecf2959f..7012ba369 100644 --- a/web/config/sync/jsonapi_extras.jsonapi_resource_config.node--wfo_pdf_uploads.yml +++ b/web/config/sync/jsonapi_extras.jsonapi_resource_config.node--wfo_pdf_upload.yml @@ -3,16 +3,16 @@ langcode: en status: true dependencies: config: - - node.type.wfo_pdf_uploads + - node.type.wfo_pdf_upload module: - jsonapi_defaults third_party_settings: jsonapi_defaults: page_limit: 50 -id: node--wfo_pdf_uploads +id: node--wfo_pdf_upload disabled: false -path: node/wfo_pdf_uploads -resourceType: node--wfo_pdf_uploads +path: node/wfo_pdf_upload +resourceType: node--wfo_pdf_upload resourceFields: nid: disabled: true diff --git a/web/config/sync/language.content_settings.node.wfo_pdf_uploads.yml b/web/config/sync/language.content_settings.node.wfo_pdf_upload.yml similarity index 65% rename from web/config/sync/language.content_settings.node.wfo_pdf_uploads.yml rename to web/config/sync/language.content_settings.node.wfo_pdf_upload.yml index 32e110b46..b2fa2fb6d 100644 --- a/web/config/sync/language.content_settings.node.wfo_pdf_uploads.yml +++ b/web/config/sync/language.content_settings.node.wfo_pdf_upload.yml @@ -3,9 +3,9 @@ langcode: en status: true dependencies: config: - - node.type.wfo_pdf_uploads -id: node.wfo_pdf_uploads + - node.type.wfo_pdf_upload +id: node.wfo_pdf_upload target_entity_type_id: node -target_bundle: wfo_pdf_uploads +target_bundle: wfo_pdf_upload default_langcode: zxx language_alterable: false diff --git a/web/config/sync/node.type.wfo_pdf_uploads.yml b/web/config/sync/node.type.wfo_pdf_upload.yml similarity index 97% rename from web/config/sync/node.type.wfo_pdf_uploads.yml rename to web/config/sync/node.type.wfo_pdf_upload.yml index 7da061af1..d16bf94c5 100644 --- a/web/config/sync/node.type.wfo_pdf_uploads.yml +++ b/web/config/sync/node.type.wfo_pdf_upload.yml @@ -27,7 +27,7 @@ third_party_settings: unique: 0 unique_text: '' name: 'WFO PDF upload' -type: wfo_pdf_uploads +type: wfo_pdf_upload description: 'PDFs that are produced by a WFO, using the DSS Builder (Google Slides) and applicable to any location within their WCA.' help: null new_revision: false diff --git a/web/config/sync/user.role.uploader.yml b/web/config/sync/user.role.uploader.yml index ac6aaeffe..061c983fe 100644 --- a/web/config/sync/user.role.uploader.yml +++ b/web/config/sync/user.role.uploader.yml @@ -3,7 +3,7 @@ langcode: en status: true dependencies: config: - - node.type.wfo_pdf_uploads + - node.type.wfo_pdf_upload module: - node id: uploader @@ -11,4 +11,4 @@ label: Uploader weight: -4 is_admin: null permissions: - - 'create wfo_pdf_uploads content' + - 'create wfo_pdf_upload content' From d7e05f443a89f4c3398bbaa67c5d12fcc0398e35 Mon Sep 17 00:00:00 2001 From: James Tranovich Date: Wed, 28 Aug 2024 11:54:42 -0700 Subject: [PATCH 14/22] api: add python script for integration purposes --- docs/dev/json-api-upload-example.py | 69 +++++++++++++++++++++++++++++ docs/dev/json-api.md | 4 ++ 2 files changed, 73 insertions(+) create mode 100644 docs/dev/json-api-upload-example.py diff --git a/docs/dev/json-api-upload-example.py b/docs/dev/json-api-upload-example.py new file mode 100644 index 000000000..3249d14a3 --- /dev/null +++ b/docs/dev/json-api-upload-example.py @@ -0,0 +1,69 @@ +#!/usr/bin/env python + +import requests # https://pypi.org/project/requests/ +import subprocess +import base64 +import os +import sys + +# This is a sample python script to demonstrate how to upload a WFO daily +# situation report, which is produced as a PDF. This script is for educational +# purposes only and is intended to aid as a helper for integration. + +# configuration options +endpoint = 'http://localhost:8080' +user = 'uploader' +password = 'uploader' +pdf_filename = 'test.pdf' + +# if we don't have one already, create a pdf for uploading; requires magick +if not os.path.exists(pdf_filename): + _ = subprocess.run(['magick', 'xc:none', '-page', 'Letter', pdf_filename]) + +pdf_data = open(pdf_filename, 'rb').read() + +# first step: upload the pdf file +headers = { + 'Accept': 'application/vnd.api+json', + 'Content-Type': 'application/octet-stream', + 'Content-Disposition': f'file; filename="{pdf_filename}"', +} +resp = requests.post(f'{endpoint}/jsonapi/node/wfo_pdf_upload/field_wfo_sitrep', + data=pdf_data, + headers=headers, + auth=(user, password)) +if resp.status_code != 201: + print(f'could not upload pdf: {resp.text}') + sys.exit(1) +print(f'successfully uploaded pdf: {resp.json()}') + +# second step: grab the ID of the file we just uploaded +uploaded_file_id = resp.json()['data']['id'] + +# last step: create the wfo_pdf_upload type +payload = { + 'data': { + 'type': 'node--wfo_pdf_upload', + 'attributes': { + 'title': pdf_filename, + }, + 'relationships': { + 'field_wfo_sitrep': { + 'data': { + 'type': 'file--file', + 'id': uploaded_file_id, + } + } + } + } +} +headers = { + 'Accept': 'application/vnd.api+json', + 'Content-Type': 'application/vnd.api+json', +} +resp = requests.post(f'{endpoint}/jsonapi/node/wfo_pdf_upload', json=payload, headers=headers, auth=(user, password)) +if resp.status_code != 201: + print(f'could not finish wfo pdf upload: {resp.text}') + sys.exit(1) + +print(f'created a new WFO daily situation report: {resp.json()}') diff --git a/docs/dev/json-api.md b/docs/dev/json-api.md index 9049a75fa..4a5fce9c8 100644 --- a/docs/dev/json-api.md +++ b/docs/dev/json-api.md @@ -65,3 +65,7 @@ Second, we create the `wfo_pdf_upload` entity itself and link the PDF `id`: http://localhost:8080/jsonapi/node/wfo_pdf_upload The response should also be a 201 with JSON information about the newly created `wfo_pdf_upload` entity. + +# Integration Example + +A sample [Python script](../json-api-upload-example.py) is provided to help to aid in integration. Note that this script depends on the [requests](https://pypi.org/project/requests/) library. From 445290095326828353a598b277ca4e89f6500986 Mon Sep 17 00:00:00 2001 From: James Tranovich Date: Wed, 28 Aug 2024 13:31:45 -0700 Subject: [PATCH 15/22] apache2 configuration tweaking --- .../httpd-block-api-get-requests.conf | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/.bp-config/httpd/user-provided/httpd-block-api-get-requests.conf b/.bp-config/httpd/user-provided/httpd-block-api-get-requests.conf index 09065c527..5edb80e15 100644 --- a/.bp-config/httpd/user-provided/httpd-block-api-get-requests.conf +++ b/.bp-config/httpd/user-provided/httpd-block-api-get-requests.conf @@ -1,8 +1,10 @@ -# Enable rewriting so we can block JSON:API GET requests +# enable rewriting so we can block certain JSON:API requests LoadModule rewrite_module modules/mod_rewrite.so - - RewriteEngine On - RewriteCond %{REQUEST_METHOD} ^(GET|DELETE|PUT) [NC] - RewriteRule .* - [F,L] - +RewriteEngine On +RewriteCond "%{REQUEST_URI}" ^/jsonapi/.* +RewriteCond "%{REQUEST_METHOD}" ^(GET|DELETE|PUT) [nocase] +RewriteRule ".*" - [forbidden,last] +# let through other requests +RewriteCond "%{REQUEST_URI}" ^/jsonapi/.* +RewriteRule "(.*)" "$1" [passthrough] From 3c435e2b140b979db4c8830c3f53c9e09ef1521e Mon Sep 17 00:00:00 2001 From: James Tranovich Date: Wed, 28 Aug 2024 14:20:57 -0700 Subject: [PATCH 16/22] revert apache2 changes --- .../user-provided/httpd-block-api-get-requests.conf | 10 ---------- docker-compose.yml | 3 --- docs/dev/json-api.md | 4 +--- 3 files changed, 1 insertion(+), 16 deletions(-) delete mode 100644 .bp-config/httpd/user-provided/httpd-block-api-get-requests.conf diff --git a/.bp-config/httpd/user-provided/httpd-block-api-get-requests.conf b/.bp-config/httpd/user-provided/httpd-block-api-get-requests.conf deleted file mode 100644 index 5edb80e15..000000000 --- a/.bp-config/httpd/user-provided/httpd-block-api-get-requests.conf +++ /dev/null @@ -1,10 +0,0 @@ -# enable rewriting so we can block certain JSON:API requests -LoadModule rewrite_module modules/mod_rewrite.so - -RewriteEngine On -RewriteCond "%{REQUEST_URI}" ^/jsonapi/.* -RewriteCond "%{REQUEST_METHOD}" ^(GET|DELETE|PUT) [nocase] -RewriteRule ".*" - [forbidden,last] -# let through other requests -RewriteCond "%{REQUEST_URI}" ^/jsonapi/.* -RewriteRule "(.*)" "$1" [passthrough] diff --git a/docker-compose.yml b/docker-compose.yml index 10056bad5..cf1e9ac2a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -82,9 +82,6 @@ services: # Map in our test coverage directory so we can have those pretty outputs. - ./.coverage:/coverage - # Map specific apache2 conf settings (optional) - # - ./.bp-config/httpd/user-provided/httpd-block-api-get-requests.conf:/etc/apache2/conf-enabled/httpd-block-api-get-requests.conf - plantuml: build: context: ./ diff --git a/docs/dev/json-api.md b/docs/dev/json-api.md index 4a5fce9c8..9871533e4 100644 --- a/docs/dev/json-api.md +++ b/docs/dev/json-api.md @@ -19,9 +19,7 @@ We have configured JSON:API to only display `wfo_pdf_upload`s and `file`s. (The We have also configured a new user type, `uploader`, which has no permissions except to create new `wfo_pdf_upload`s. -Because JSON:API follows Drupal entity permissions, JSON:API also respects the user permissions for that entity type. This means that currently `anonymous` users can browse the JSON API, including viewing `file`s and `wfo_pdf_upload`s, because `anonymous` users can `view published content`. - -Because we do not have an use case for listing resources, we are blocking all `GET` requests for the JSON:API via an [Apache configuration](../../.bp-config/httpd/user-provided/httpd-block-api-get-requests.conf). +Because JSON:API follows Drupal entity permissions, JSON:API also respects the user permissions for that entity type. This means that currently `anonymous` users can browse the JSON API, including viewing `file`s and `wfo_pdf_upload`s, because `anonymous` users can `view published content`. (This will change in a later version.) # Example From b712c9a56288257e6d76cb24b733f2c5de27d505 Mon Sep 17 00:00:00 2001 From: James Tranovich Date: Wed, 28 Aug 2024 17:04:39 -0700 Subject: [PATCH 17/22] alter json api routes to require role: uploader --- .../JsonApiLimitingRouteSubscriber.php | 28 +++++++++++++++++++ .../weather_login/weather_login.services.yml | 4 +++ 2 files changed, 32 insertions(+) create mode 100644 web/modules/weather_login/src/Routing/JsonApiLimitingRouteSubscriber.php diff --git a/web/modules/weather_login/src/Routing/JsonApiLimitingRouteSubscriber.php b/web/modules/weather_login/src/Routing/JsonApiLimitingRouteSubscriber.php new file mode 100644 index 000000000..8b53e6694 --- /dev/null +++ b/web/modules/weather_login/src/Routing/JsonApiLimitingRouteSubscriber.php @@ -0,0 +1,28 @@ +mutableResourceTypes(); + foreach ($collection as $name => $route) { + $defaults = $route->getDefaults(); + if (!empty($defaults['_is_jsonapi'])) { + $route->setRequirement('_role', 'uploader'); + } + } + } + + private function mutableResourceTypes(): array { + return [ + 'file--file' => TRUE, + 'node--wfo_pdf_upload' => TRUE, + ]; + } +} diff --git a/web/modules/weather_login/weather_login.services.yml b/web/modules/weather_login/weather_login.services.yml index 26dc6f214..80a04ec32 100644 --- a/web/modules/weather_login/weather_login.services.yml +++ b/web/modules/weather_login/weather_login.services.yml @@ -3,3 +3,7 @@ services: class: Drupal\weather_login\RouteSubscriber\UserLoginRouteSubscriber tags: - { name: event_subscriber } + weather_login.route_subscriber: + class: Drupal\weather_login\Routing\JsonApiLimitingRouteSubscriber + tags: + - { name: event_subscriber } From ee8d60a3b84176d0c75c5f91dd538f70592cf0d6 Mon Sep 17 00:00:00 2001 From: James Tranovich Date: Wed, 28 Aug 2024 17:10:44 -0700 Subject: [PATCH 18/22] removed mutable types: not needed --- .../src/Routing/JsonApiLimitingRouteSubscriber.php | 8 -------- 1 file changed, 8 deletions(-) diff --git a/web/modules/weather_login/src/Routing/JsonApiLimitingRouteSubscriber.php b/web/modules/weather_login/src/Routing/JsonApiLimitingRouteSubscriber.php index 8b53e6694..bc6c6b0b0 100644 --- a/web/modules/weather_login/src/Routing/JsonApiLimitingRouteSubscriber.php +++ b/web/modules/weather_login/src/Routing/JsonApiLimitingRouteSubscriber.php @@ -10,7 +10,6 @@ class JsonApiLimitingRouteSubscriber extends RouteSubscriberBase { * {@inheritdoc} */ protected function alterRoutes(RouteCollection $collection) { - $mutable_types = $this->mutableResourceTypes(); foreach ($collection as $name => $route) { $defaults = $route->getDefaults(); if (!empty($defaults['_is_jsonapi'])) { @@ -18,11 +17,4 @@ protected function alterRoutes(RouteCollection $collection) { } } } - - private function mutableResourceTypes(): array { - return [ - 'file--file' => TRUE, - 'node--wfo_pdf_upload' => TRUE, - ]; - } } From b26322d7d104d11bd4c575660f4d46f78175d657 Mon Sep 17 00:00:00 2001 From: James Tranovich Date: Wed, 28 Aug 2024 17:41:57 -0700 Subject: [PATCH 19/22] php formatting --- .../src/Routing/JsonApiLimitingRouteSubscriber.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/web/modules/weather_login/src/Routing/JsonApiLimitingRouteSubscriber.php b/web/modules/weather_login/src/Routing/JsonApiLimitingRouteSubscriber.php index bc6c6b0b0..7d015fb8e 100644 --- a/web/modules/weather_login/src/Routing/JsonApiLimitingRouteSubscriber.php +++ b/web/modules/weather_login/src/Routing/JsonApiLimitingRouteSubscriber.php @@ -5,11 +5,13 @@ use Drupal\Core\Routing\RouteSubscriberBase; use Symfony\Component\Routing\RouteCollection; -class JsonApiLimitingRouteSubscriber extends RouteSubscriberBase { +class JsonApiLimitingRouteSubscriber extends RouteSubscriberBase +{ /** * {@inheritdoc} */ - protected function alterRoutes(RouteCollection $collection) { + protected function alterRoutes(RouteCollection $collection) + { foreach ($collection as $name => $route) { $defaults = $route->getDefaults(); if (!empty($defaults['_is_jsonapi'])) { From 94c9949ecd349cffa979908b2e070963e7f41a6f Mon Sep 17 00:00:00 2001 From: James Tranovich Date: Thu, 29 Aug 2024 08:18:20 -0700 Subject: [PATCH 20/22] added documentation --- docs/dev/json-api.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dev/json-api.md b/docs/dev/json-api.md index 9871533e4..23246c960 100644 --- a/docs/dev/json-api.md +++ b/docs/dev/json-api.md @@ -19,7 +19,7 @@ We have configured JSON:API to only display `wfo_pdf_upload`s and `file`s. (The We have also configured a new user type, `uploader`, which has no permissions except to create new `wfo_pdf_upload`s. -Because JSON:API follows Drupal entity permissions, JSON:API also respects the user permissions for that entity type. This means that currently `anonymous` users can browse the JSON API, including viewing `file`s and `wfo_pdf_upload`s, because `anonymous` users can `view published content`. (This will change in a later version.) +Because JSON:API follows Drupal entity permissions, JSON:API also respects the user permissions for that entity type. This permission system is not sufficient in and of itself (for example, `anonymous` users could browse the JSON API, including viewing `file`s and `wfo_pdf_upload`s, because `anonymous` users can `view published content`.). So, to further restrict access, we have added a `JsonApiLimitingRouteSubscriber` that mandates `uploader` permissions for the API. All other users will get a `403` response. # Example From b428584fc79ded843d5156d8eac3f0f22958b4d3 Mon Sep 17 00:00:00 2001 From: James Tranovich Date: Thu, 29 Aug 2024 08:37:15 -0700 Subject: [PATCH 21/22] documentation tweak --- docs/dev/json-api.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dev/json-api.md b/docs/dev/json-api.md index 23246c960..c53fbc9e0 100644 --- a/docs/dev/json-api.md +++ b/docs/dev/json-api.md @@ -19,7 +19,7 @@ We have configured JSON:API to only display `wfo_pdf_upload`s and `file`s. (The We have also configured a new user type, `uploader`, which has no permissions except to create new `wfo_pdf_upload`s. -Because JSON:API follows Drupal entity permissions, JSON:API also respects the user permissions for that entity type. This permission system is not sufficient in and of itself (for example, `anonymous` users could browse the JSON API, including viewing `file`s and `wfo_pdf_upload`s, because `anonymous` users can `view published content`.). So, to further restrict access, we have added a `JsonApiLimitingRouteSubscriber` that mandates `uploader` permissions for the API. All other users will get a `403` response. +Because JSON:API follows Drupal entity permissions, JSON:API also respects the user permissions for that entity type. This permission system is not sufficient in and of itself (for example, `anonymous` users could browse the JSON API, including viewing `file`s and `wfo_pdf_upload`s, because `anonymous` users can `view published content`.). So, to further restrict access, we have added a `JsonApiLimitingRouteSubscriber` that mandates an `uploader` role for the API. All other users will get a `403` response. # Example From dcc8720c7ae6ea3dc1832bc8fb24503b7ad5ce22 Mon Sep 17 00:00:00 2001 From: James Tranovich Date: Thu, 29 Aug 2024 11:47:36 -0700 Subject: [PATCH 22/22] move JsonApiLimitingRouteSubscriber to weather_cms --- .../src/Routing/JsonApiLimitingRouteSubscriber.php | 2 +- web/modules/weather_cms/weather_cms.services.yml | 5 +++++ web/modules/weather_login/weather_login.services.yml | 4 ---- 3 files changed, 6 insertions(+), 5 deletions(-) rename web/modules/{weather_login => weather_cms}/src/Routing/JsonApiLimitingRouteSubscriber.php (92%) diff --git a/web/modules/weather_login/src/Routing/JsonApiLimitingRouteSubscriber.php b/web/modules/weather_cms/src/Routing/JsonApiLimitingRouteSubscriber.php similarity index 92% rename from web/modules/weather_login/src/Routing/JsonApiLimitingRouteSubscriber.php rename to web/modules/weather_cms/src/Routing/JsonApiLimitingRouteSubscriber.php index 7d015fb8e..a145a934a 100644 --- a/web/modules/weather_login/src/Routing/JsonApiLimitingRouteSubscriber.php +++ b/web/modules/weather_cms/src/Routing/JsonApiLimitingRouteSubscriber.php @@ -1,6 +1,6 @@