Fields values the user has view but not edit access can be saved to AutoSave

Created on 29 May 2025, 4 days ago

Overview

Split off from ๐Ÿ“Œ [PP-1] Add entity access checks to routes that deal with entities Postponed

We discovered there that the experience_builder.api.layout.post would allow fields to be set in the auto-save for which user has view but not edit access.

The example we found was sticky.

If this was sent when currently sticky === false, it would end up in the auto-save

'entity_form_fields' => [
        'sticky' => TRUE,
      ],

How this happens:

  1. \Drupal\experience_builder\Controller\ApiLayoutController::post() calls \Drupal\experience_builder\Controller\ApiLayoutController::buildPreviewRenderable() with $updateAutoSave === TRUE
  2. \Drupal\experience_builder\ClientDataToEntityConverter::convert() called and in \Drupal\experience_builder\ClientDataToEntityConverter::setEntityFields() does a bunch of logic to run entity_form_fields through the form submission process.
  3. Then we get to the loop that is going to actually set the field values in the entity
    foreach ($entity_form_fields as $field_name => $field_value) {
    

    At this point $entity_form_fields === ['sticky' => 1]
    but what we will actually be using compare the new and old value is $entity->get('sticky')

  4. $entity->get('sticky') has actually been changed by the form process back to false. NOT was sent by the client
  5. So when ClientDataToEntityConverter::checkPatchFieldAccess is called we get to
    if ($original_field->access('view') && $original_field->equals($received_field)) {
          return FALSE;
        }
    

    This is meant to allow the client to send the current values of field if they can view them but not edit them.

    So we return FALSE which will trigger this

    if (!$this->checkPatchFieldAccess($original_field, $entity->get($field_name))) {
              $entity->set($field_name, $original_field->getValue());
            }
    

    ๐Ÿ™We reset the field to it's original value, and we do not throw an AccessException in checkPatchFieldAccess()

    This probably not ideal but we do prevent $entity->get('sticky') from being set. This is important because this also to make real entity saves in \Drupal\experience_builder\Controller\ApiAutoSaveController::post()

  6. Then
    // Filter out form values that are not accessible to the client.
    $values = self::filterFormValues($form_state->getValues(), $form);
    
NOT DONE WITH SUMMARY PLEASE LET ME FINISH BEFORE ISSUE IS WORKED ON ETC(๐Ÿ™tedbow)

Proposed resolution

User interface changes

๐Ÿ› Bug report
Status

Needs work

Version

0.0

Component

Auto-save

Created by

๐Ÿ‡บ๐Ÿ‡ธUnited States tedbow Ithaca, NY, USA

Live updates comments and jobs are added and updated live.
  • Needs issue summary update

    Issue summaries save everyone time if they are kept up-to-date. See Update issue summary task instructions.

Sign in to follow issues

Merge Requests

Comments & Activities

Production build 0.71.5 2024