We use revisions and content moderation heavily on node and sometimes owner of the node changes during article updates (node have published default revision + editor works on new version which is not published yet). It makes problem for second user, he is not able to edit the paragraphs he sees the lock icon on the paragraphs. If i check what user gets in ParagraphAccessControlHandler::checkAccess he gets default revision of the node in method getParentEntity() which is not correct... actually on the form he works on different revision and thats the reason he sees lock. Am I alone with this problem and we do have some issue on our project or is it an issue in the module / getParentEntity?

Comments

mkolar created an issue. See original summary.

snitta’s picture

Same here.

In my case users with specific roles couldn't edit paragraphs even when they could access node edit page if the following conditions were met:
1. the node's default revision and latest revision are different
2. the users can't edit the default revision

As mkolar noted the cause is getParentEntity() loading wrong revision.

sukanya.ramakrishnan’s picture

Facing the same issue!

sukanya.ramakrishnan’s picture

Ok, the issue is the way the parent entity is referenced in the access check. Instead of getting the current revision, the default revision is getting loaded.

We need to check if the parent entity is revisionable and check the latest version for access!

sukanya.ramakrishnan’s picture

Adding a basic fix to get things going! Experts kindly advise if the revision is being loaded correctly! Needs extensive testing for non revisionable entities and translations!

Thanks
Sukanya

sukanya.ramakrishnan’s picture

Status: Active » Needs review

Setting to needs review, thanks!

bkosborne’s picture

Title: Access check - Parent entity revision owner issue (getParentEntity) » Paragraph access check via parent entity incorrectly uses the default revision of the parent instead of the latest

Clarified title

idebr’s picture

Version: 8.x-1.9 » 8.x-1.x-dev
StatusFileSize
new4.04 KB
new3.89 KB

Attached patch implements the following changes:

  1. Fixed PHPLint errors
  2. Replaced calls to deprecated code
  3. Implemented strict comparison checks

Status: Needs review » Needs work

The last submitted patch, 8: 3084934-8.patch, failed testing. View results

idebr’s picture

Status: Needs work » Needs review
StatusFileSize
new2 KB
new4.09 KB

Attached patch implements the following changes:

  1. Limit the access check to operations other than view to prevent less privileged users from losing access to content (see test failures in #8)
lendude’s picture

+++ b/src/ParagraphAccessControlHandler.php
@@ -61,15 +75,25 @@ class ParagraphAccessControlHandler extends EntityAccessControlHandler implement
+        // Load the latest revision if the parent entity is revisionable and not
+        // new.
+        if ($storage instanceof TranslatableRevisionableStorageInterface && !$parent_entity->isNew()) {
+          $parent_entity_id = $storage->getLatestTranslationAffectedRevisionId($parent_entity->id(), $parent_entity->language()->getId());

Neither the comment nor the IS mention why this would only be the case for Translatable content. Is there a reason? Or should we also cover non-Translatable content here?

aloneblood’s picture

StatusFileSize
new4.33 KB

Add multilingual support for 3084934-10.patch

Status: Needs review » Needs work

The last submitted patch, 12: 3084934-12.patch, failed testing. View results

aloneblood’s picture

StatusFileSize
new4.34 KB

Add multilingual support for 3084934-10.patch

mrshowerman’s picture

Status: Needs work » Needs review
StatusFileSize
new4.81 KB
new2.6 KB

I have the same issue, but a slightly different use case:

  1. Allow authenticated users to view unpublished paragraphs
  2. Create two nested paragraph types (A and B), A referencing B.
  3. Edit a node, add an unpublished instance of paragraph type A, referencing a published instance of paragraph type B.
  4. Save the node as published, which makes the unpublished revision of type A the default revision.
  5. Edit the node again, make parapgraph A published, save the node as a draft.
  6. View the node with an authenticated user

Expected result: paragraphs A and B are visible, due to the fact that the latest revisions of both paragraphs are published.

Actual result: paragraph A is visible, but not paragraph B. This is because the aforementioned parent entity access check for paragraph B looks at paragraph A's default revision, not the latest one.

Since the "view" permission had been ignored since #10 for good reasons, I had to add some more permission checks. Hope this doesn't fail the tests.

Also tried to address #11.

Status: Needs review » Needs work

The last submitted patch, 15: 3084934-15.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

mrshowerman’s picture

Status: Needs work » Needs review
StatusFileSize
new4.94 KB
new2.73 KB

Thought again about the right way to determine if we should check the latest parent revision when the permission is "view".

The other test fails might be related to PHP 7.3, not sure why that version was used in the test.

Status: Needs review » Needs work

The last submitted patch, 17: 3084934-17.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

artyom hovasapyan’s picture

StatusFileSize
new4.93 KB

Update #17 change andIf to orIf

le72’s picture

This is still an issue in our project. Any progress here? Patch #17 and/or #19 are looking promising.

mrshowerman’s picture

Status: Needs work » Needs review

#17 passes test when run against PHP 7.4, so setting back to NR.
@Artyom Hovasapyan, can you explain your change and also provide an interdiff?

Status: Needs review » Needs work

The last submitted patch, 19: 3084934-18.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

artyom hovasapyan’s picture

Our project like this
1` enable drupal core module workflow (revision levels)
2` have translator roles (can only translate content)
3` when I created Node(draft version) and that time translator can not change paragraph(it's OK) but when change draft to In translation that moment Translator can not translate paragraph (It's wrong)
Thereby I offer change andIf to orIf . It's work correct (for me).

bkosborne’s picture

Is loading the latest revision really the solution? Shouldn't the access check load the revision of the parent that this specific paragraph revision is attached to? That's not necessarily the latest revision, is it? I guess for the use case of editing, it is true that the latest revision is what should be loaded. But for viewing, I don't think so. For example, if I'm reviewing an older revision of a node, when the access check is run on the paragraph on that node revision, it should be checking if the user has access to view that specific revision of the node, not the latest revision of that node.

I don't think there's a way we can solve this because paragraph entities don't actually know what revision they're attached to. They only know what the entity ID is.

I think this cannot be solved correctly until #2954512: Store information about a paragraph's parent revision.

However, for the edit operation, I suppose we could assume that it's safe to always check the latest revision, which is something we can do.

bkosborne’s picture

#3090200: Paragraph view access check using incorrect revision of its parent, leading to issues viewing paragraphs when reverted host entities or content moderation is used is basically the same as this issue, though that one primarily deals with the "view" operation not working right, and this issue deals with the "update" operation not working right. At the root of both is the problem that Paragraphs don't know what revision they are attached to. The latest patches in both these issues is essentially identical, they're both trying to load the latest revision of the parent which is not correct. In any case, I'm going to close this issue as a duplicate so efforts can be concentrated. That issue has more comments & activity and the issue summary is more detailed.