Problem/Motivation

A client reported that some field values weren't showing up on the preview link of a node.

The node is published, and the content being referenced is also published. The field is rendered using core's EntityReferenceLabelFormatter.

Debugging into it, preview_link_entity_access is returning forbidden for the referenced node because the tokens do not match.

This would only happen when the referenced entity also has a preview link entity, since PreviewLinkAccessCheck::access returns early when there isn't one.

This should be pretty easy to write a failing test for, the solution might be a bit more involved though.

Proposed resolution

Check the entity id from the route match against the entity passed into preview_link_entity_access and return neutral if they don't match?

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

acbramley created an issue. See original summary.

acbramley’s picture

Status: Active » Needs review
StatusFileSize
new2.9 KB
new4.06 KB

Here's a potential fix and a test which should be failing for the test-only version but for some reason it's not. Running an identical workflow in a test environment does correctly fail so I'm not too sure what's going on there, maybe some weird caching or something?

jibran’s picture

+++ b/preview_link.module
@@ -75,8 +75,24 @@ function preview_link_entity_access(EntityInterface $entity, $operation, Account
+  $route_match = \Drupal::routeMatch();
+  $entity_type_ids = array_keys(\Drupal::entityTypeManager()->getDefinitions());
+  $route_entity = NULL;
+  foreach ($entity_type_ids as $entity_type_id) {
+    if ($route_entity = $route_match->getParameter($entity_type_id)) {
+      break;
+    }
+  }

I wish core should provide an API for this. Here is another issue #3047936: Generic support for any entity type where we wanted to do the same

acbramley’s picture

@jibran agreed, there's a few modules that would benefit from this.

jibran’s picture

acbramley’s picture

StatusFileSize
new4.09 KB
new644 bytes

#2 was throwing 500s for some users on revision routes. It's interesting that this module's access hook even runs on non-preview link routes but that's a separate issue.

FYI: The test still needs work.

dpi’s picture

Status: Needs review » Needs work
+++ b/preview_link.module
@@ -75,8 +75,24 @@ function preview_link_entity_access(EntityInterface $entity, $operation, Account
+  $route_match = \Drupal::routeMatch();
+  $entity_type_ids = array_keys(\Drupal::entityTypeManager()->getDefinitions());
+  $route_entity = NULL;
+  foreach ($entity_type_ids as $entity_type_id) {
+    if ($route_entity = $route_match->getParameter($entity_type_id)) {
+      break;
+    }
+  }

This should probably get the route option preview_link.entity_type_id, similar to PreviewLinkController::resolveEntity, instead of iterating parameters.

edit: See below

dpi’s picture

Version: 8.x-1.x-dev » 2.0.x-dev
StatusFileSize
new1.18 KB
new4.01 KB

I wish core should provide an API for this. Here is another issue #3047936: Generic support for any entity type where we wanted to do the same

301 #3138465: Add a generic entity route context

--

Uploaded reroll + 7 feedback

dpi’s picture

Actually I think I may have gotten the intent of the change wrong :/ In which case a new test is necessary.

dpi’s picture

StatusFileSize
new4.1 KB

Just the reroll

dpi’s picture

Making a list of issues which would find service outlined in #3138465: Add a generic entity route context useful.

acbramley’s picture

Status: Needs work » Reviewed & tested by the community
sam152’s picture

  1. +++ b/preview_link.module
    @@ -69,10 +69,26 @@ function preview_link_entity_access(EntityInterface $entity, $operation, Account
    +  $route_match = \Drupal::routeMatch();
    +  $entity_type_ids = array_keys(\Drupal::entityTypeManager()->getDefinitions());
    +  $route_entity = NULL;
    +  foreach ($entity_type_ids as $entity_type_id) {
    +    if ($route_entity = $route_match->getParameter($entity_type_id)) {
    +      break;
    +    }
    +  }
    

    Could simplify with the following?

      $route_match = \Drupal::routeMatch();
      $route_entity = NULL;
      if ($preview_link_entity_type = $route_match->getRouteObject()->getOption('preview_link.entity_type_id')) {
        $route_entity = $route_match->getParameter($preview_link_entity_type);
      }
    
  2. +++ b/preview_link.module
    @@ -69,10 +69,26 @@ function preview_link_entity_access(EntityInterface $entity, $operation, Account
    +  // Only run our access checks on the entity we're previewing.
    +  if ($route_entity instanceof ContentEntityInterface && $route_entity->id() === $entity->id()) {
    +    return \Drupal::service('access_check.preview_link')->access($entity, $route_match->getParameter('preview_token'));
    +  }
    

    What if two different entity types have the same ID?

  3. I guess the last thing to sanity check would be the cacheability. It seems okay to me, since I don't think access results themselves are cached, they just inform the cacheability of the objects the entities are embedded in? Ie, for a specific entity returning neutral on preview link route A and allowed on preview link route B is fine because they are two different routes?

    Still not completely sure, it's a bit mind bending...

sam152’s picture

Status: Reviewed & tested by the community » Needs work

Also failing to apply.

suresh prabhu parkala’s picture

StatusFileSize
new4.13 KB

Just a re-roll.

larowlan made their first commit to this issue’s fork.

acbramley’s picture

Status: Needs work » Needs review
acbramley’s picture

StatusFileSize
new4.24 KB
dpi’s picture

Status: Needs review » Reviewed & tested by the community

The calls out to routematch in an access always scare me so much, considering history in this project. So long as we have coverage should be alright.

CI reports a minor CS error.

For caution sake, can we make sure we tag this as a non stable release (alpha/beta/RC) and have it get a little bit of usage before we release it widely.

  • acbramley committed c0203de on 2.0.x
    Issue #3117258 by dpi, acbramley, larowlan, Suresh Prabhu Parkala,...
acbramley’s picture

Status: Reviewed & tested by the community » Fixed

Thanks! Fixed CS on commit.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.