ApiLayoutController::buildPreviewRenderable unnecessarily call \ClientDataToEntityConverter::converts causing errors

Created on 18 April 2025, 1 day ago

Overview

Founding when researching πŸ“Œ [PP-1] Update `experience_builder.(experience_builder|api.layout.get) routes` to respect content entity update/field edit access of edited XB field Active

How to reproduce

  1. user 1, has path edit access, user 2 does NOT have path edit access. Both have access to have other XB permissions
  2. user 1 uses XB with node 1 and sets path to /my-page
  3. user 2 uses XB with node 1

Right user 2 will get an error.

This because \Drupal\experience_builder\Controller\ApiLayoutController::get() will

return new PreviewEnvelope($this->buildPreviewRenderable($data, $entity, FALSE), $data);

The FALSE here is for $updateAutoSave

buildPreviewRenderable has

$updated_entity_form_fields = $this->converter->convert([
      'layout' => $content,
      // An empty model needs to be represented as \stdClass so that it is
      // correctly json encoded. But we need to convert it to an array before
      // we can extract it.
      'model' => (array) $model,
      'entity_form_fields' => $body['entity_form_fields'],
    ], $entity, validate: FALSE);
    // Store the auto-save entry.
    if ($updateAutoSave) {
      $this->autoSaveManager->save($entity, [
        'layout' => [$content],
        // An empty model needs to be represented as \stdClass so that it is
        // correctly json encoded. But we need to convert it to an array before
        // we can extract it.
        'model' => self::extractModelForSubtree($content, (array) $model),
        // Store the updated form build ID but leave all other fields as-is.
        // This allows us to re-submit the values from auto-save when we finally
        // publish the entity. Some field widgets make transformations to the form
        // data which cannot be repeated.
        // @see \Drupal\Core\Field\Plugin\Field\FieldWidget\OptionsWidgetBase::validateElement
        'entity_form_fields' => \array_filter([
          'form_build_id' => $updated_entity_form_fields['form_build_id'] ?? NULL,
        ]) + $body['entity_form_fields'],
      ]);

convert() will check the field access on but since user 2 doesn't have edit access for path and path is in the auto-save it will throw an error.

But $updated_entity_form_fields is only used inside the if block if $updateAutoSave. so there is no reason to call it outside of the if block

Proposed resolution

In buildPreviewRenderable() move the call to convert() inside the if ($updateAutoSave) {

While this doesn't solve the problems πŸ“Œ [PP-1] Add entity access checks to routes that deal with entities Postponed it does start to untangle it. There is no real reason the user should not be able preview the layout here, it was just simple var placement problem

User interface changes

πŸ› Bug report
Status

Active

Version

0.0

Component

Page builder

Created by

πŸ‡ΊπŸ‡ΈUnited States tedbow Ithaca, NY, USA

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

Production build 0.71.5 2024