Problem/Motivation

Disabled resources are still accessible via the related, relationship and includes. They should not be available if they are disabled, even if that breaks the full linkage principle.

Proposed resolution

Use the resource type repository to determine if a referenced resource is available or not.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

e0ipso created an issue. See original summary.

e0ipso’s picture

Initial patch.

Status: Needs review » Needs work

The last submitted patch, 2: 2933615--fix-related-relationship-disabled--2.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

e0ipso’s picture

e0ipso’s picture

e0ipso’s picture

Status: Needs work » Needs review
e0ipso’s picture

Status: Needs review » Fixed

Merging to unblock testing PR for JSON API Extras.

  • e0ipso committed 9889be7 on 8.x-1.x
    Issue #2933615 by e0ipso: Fix related and relationships endpoints for...
gabesullice’s picture

Status: Fixed » Needs work
  1. +++ b/src/Controller/EntityResource.php
    @@ -168,6 +179,9 @@ class EntityResource {
    +   * @throws \Drupal\Core\Entity\EntityStorageException
    
    @@ -214,6 +228,9 @@ class EntityResource {
    +   * @throws \Drupal\Core\Entity\EntityStorageException
    
    @@ -251,6 +268,9 @@ class EntityResource {
    +   * @throws \Drupal\Core\Entity\EntityStorageException
    

    Maybe we should catch and wrap this exception? That would allow us to provide more context about the error in our response.

  2. +++ b/src/Controller/EntityResource.php
    @@ -346,8 +369,20 @@ class EntityResource {
    +    //though the normalizer skips disabled references, we can avoid unnecessary
    +    //work by checking here too.
    

    Nit: missing spaces

    Perhaps we should find a way to combine these checks?

  3. +++ b/src/Controller/EntityResource.php
    @@ -382,13 +417,53 @@ class EntityResource {
    -    if (!($field_list = $entity->get($related_field)) || !$this->isRelationshipField($field_list)) {
    ...
    +    $field_list = $entity->get($related_field);
    +    $this->validateReferencedResource($field_list, $related_field);
    ...
    +  protected function validateReferencedResource(EntityReferenceFieldItemListInterface $field_list, $related_field) {
    +    if (!$field_list || !$this->isRelationshipField($field_list)) {
    

    I think this will throw an exception if $field_list is NULL|FALSE (even though we're checking for it in validateReferencedResource) because you've type-hinted to the interface.

  4. +++ b/src/Normalizer/RelationshipNormalizer.php
    @@ -72,6 +72,11 @@ class RelationshipNormalizer extends NormalizerBase {
    +      // If the relationship points to a disabled resource type, do not add the
    +      // normalized relationship item.
    +      if (!$relationship_item->getTargetResourceType()) {
    +        continue;
    +      }
    

    nice

e0ipso’s picture

Status: Needs work » Needs review
Issue tags: +Needs followup
FileSize
1.72 KB

Maybe we should catch and wrap this exception? That would allow us to provide more context about the error in our response.

I think that's a great idea. It's totally out of scope, so we should create a follow up instead. We should not just stop at the ones I noticed, but use static analysis to make sure we catch them all and relay them in the appropriate way.


The patch addresses the other concerns.

gabesullice’s picture

Status: Needs review » Reviewed & tested by the community
Related issues: +#2934362: Specify a "code" for every exception that JSON API throws

Patch looks good to me. Let's create that follow up or add it to the scope of #2934362: Specify a "code" for every exception that JSON API throws.

Wim Leers’s picture

Status: Reviewed & tested by the community » Needs review
+++ b/src/Controller/EntityResource.php
@@ -434,7 +434,7 @@ class EntityResource {
-  protected function validateReferencedResource(EntityReferenceFieldItemListInterface $field_list, $related_field) {
+  protected function validateReferencedResource($field_list, $related_field) {
     if (!$field_list || !$this->isRelationshipField($field_list)) {

Note that this could use
assert(is_null($field_list) || $field_list instanceof EntityReferenceFieldItemListInterface);

Any reason to not do that?

Then we at least keep the strict type checking :)

e0ipso’s picture

Status: Needs review » Needs work

The last submitted patch, 13: 2933615--fix-related-relationship-disabled--13.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

e0ipso’s picture

Status: Needs work » Fixed

Tests are passing locally. Testbot fails seem unrelated to the patch.

Merging.

  • e0ipso committed 0c8b9a3 on 8.x-1.x
    Issue #2933615 by e0ipso, Wim Leers: Fix related and relationships...
Wim Leers’s picture

Yep, that was an infra fail. #13 is green now :)

Status: Fixed » Closed (fixed)

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