Hi,

I've deliberately copied the title in #2562875: Paragraphs bundle access breaks on draft revisions because the problem is related. The patch in that issue works great and rc4 is awesome for it, but I had again the same problem: when editing a draft created from a published content, I couldn't access or modify the paragraphs on my content edit form.

My case it's been that I didn't have the "revert revisions" permission on my users. They can create, edit and delete any nodes, but not revert revisions, as our client kind of asked us to limit this permission as much as we can.

The tricky part is that permission check is done using "entity_access", which in its turn, goes to _node_revision_access() in node.module from core.

In that function there's a map of permissions:

 $map = array(
    'view' => 'view revisions',
    'update' => 'revert revisions',
    'delete' => 'delete revisions',
 );

And here you see that Drupal considers that "revert revisions" permissions is, in fact, "update" permission for revisions. And that is the permission checked for Paragraphs when editing an existing draft from an existing content.

That makes for a really weird interactions, as I can really edit my content without having the "revert revisions" permission, but I cannot edit the paragraphs because when doing access check, it asks for that specific permission.

Now, I don't really know if it's a paragraphs-related issue. I don't know if that entity_access is redundant there as I'm already editing the node, or if it's correct. I've marked this as a support request because I'm not sure this is a bug.

In the end, revert revisions doesn't do what our client thought it would do (republishing old content), so we can manage to convince them of giving this permissions without problems, but seems a bit weird that I can edit all fields of a content except paragraphs without it.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Pryrios created an issue. See original summary.

jeroen.b’s picture

I'm not really sure this is a permission problem in Paragraphs.
If entity access results in a access for the "revert revisions" permission, and you don't have that permission, you shouldn't even be able to view that node edit page.

Pryrios’s picture

Status: Active » Postponed

Well, that's probably because user has the "Content Type: edit any content" permission. I haven't tested yet what happens if user has not this permission but has "revert revisions". I find it all a little bit confusing. Maybe we should just close this issue and leave it here so that people with the same problem, can find it.

I'm marking postponed meanwhile.

jstoller’s picture

Version: 7.x-1.0-rc4 » 7.x-1.x-dev
Category: Support request » Bug report
Status: Postponed » Active

I just got bitten by this bug myself. It definitely seems like a bug. I'm just confused as to whether this is a Paragraphs bug, or a core bug?

When my non-admin users tried to edit draft revisions they were able to edit everything except paragraphs fields. Those were locked down as if they didn't have access to any of the paragraphs bundles in the field. I too was able to work around this error by giving everyone permission to revert revisions, but I don't understand why that would be necessary to edit a revision.

jbaum_13’s picture

I am having the same issue with paragraphs. When I added the permissions to revert revisions the user then had access to edit the paragraphs. The problem is that I want basic page editors to be able to edit the paragraphs but I do not want them to have the capability to revert to previous revisions.

Thank you everyone for posting the workaround!

seanbfuller’s picture

Joining in from #2665568: Paragraph and Workbench Moderation permission issue. I was able to confirm that adding the "revert revisions" permission made paragraphs editable again. The users in question did not have "administer content", but did have "content type: edit any content" permissions. We also have the situation where the users in question should be able to edit the paragraph fields, but should not be able to revert revisions. Thanks @jstoller for pointing me here.

mcalabrese’s picture

Status: Active » Needs review
FileSize
1.38 KB

The following patch resolves this issue.

It pulls in the permissions of the parent entity if it can be loaded.
I am making the assumption that a Paragraph entity will always be edited from within the parent entity.

This code could have been put inside HOOK_paragraphs_item_access(), but it seems excessive to create a module which only uses 1 hook.

gadaniels72’s picture

A little more detail on the root cause: for nodes where the revision is not the current version, entity_access calls the access callback entity_metadata_no_hook_node_access. Then, that calls _node_revision_access in the node module. That code function is what is requiring revert revision permission.

My solution, because we had this same issue, was to check to see if the entity was a node and if so, apply node access permission checks instead of entity access. This allows node access to control who can edit the paragraph item. We had a similar use case as others where basic editors need to edit but don't need to have any additional content management permissions.

Status: Needs review » Needs work

The last submitted patch, 8: paragraphs_access-2594593-8.patch, failed testing.

gadaniels72’s picture

Status: Needs work » Needs review
FileSize
1.85 KB

Updated patch so that it applies cleanly as well a fixed a hard-coded $op that i missed in patch 8.

Status: Needs review » Needs work

The last submitted patch, 10: paragraphs_access-2594593-10.patch, failed testing.

jeroen.b’s picture

Thank you @gadaniels72 for your work.
Could you add a comment to the line to the fix to say why you do the check.
Can you also explain why you don't cache the permissions when the parent entity is op type node?

I'm also currently trying to get the quality of the code up to par with the D8 version.
That mostly just means we need to add many tests to make sure we won't break anything.
Are you able to create a unit test for this? (and provide 2 patches: 1 with the fixed code + test, 1 with the test only. that way we can see the test actually confirms it is fixed now).

I understand if you don't have time/knowledge to do this, I'll probably be able to pick it up at a later time.

evucan’s picture

Hi @gadaniels72,
Thanks for the patch,
I found that after applying the patch, my admin user no longer had access to add paragraphs when adding a new page.
Anybody else get this?

ctrlADel’s picture

I found that after applying the patch, my admin user no longer had access to add paragraphs when adding a new page.
Anybody else get this?

Looks like the patch in #10 accidentally removed the return statement. I've added it back in with this patch.

ctrlADel’s picture

Turns out adding the return statement back didn't fix the issue mentioned in #13. The issue in #13 is because for a create operation node_access() expects the node type not a node object. This patch adds in the logic needed to successfully check permissions on a node create operation.

josephdpurcell’s picture

Status: Needs work » Needs review

Overall I think this looks good--moving to needs review so tests run. After applying the patch I was able to verify that a user without "revert revisions" was able to create and then edit a node with a paragraph field.

One nit pick:

+++ b/paragraphs.module
@@ -282,13 +282,24 @@ function paragraphs_paragraphs_item_access($entity, $op, $account) {
+    if ($entity->hostEntityType() == 'node') {

Add a comment explaining why nodes are a special case, noting in particular the difference between node_access and entity_access as it applies to paragraphs.

If tests pass I think this can be RTBC.

The last submitted patch, 14: paragraphs_revision_access-2594593-14.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 15: paragraphs_revision_access-2594593-15.patch, failed testing.

ctrlADel’s picture

Changed the logic a bit to hopefully fix the test failure also added in the requested comment.

josephdpurcell’s picture

Status: Needs review » Reviewed & tested by the community

This looks good. I believe the assumptions are sound in that if there is no nid permissions on the bundle should be checked, else the entity, else deny.

Setting to RTBC.

geoffreyr’s picture

Status: Reviewed & tested by the community » Needs review
FileSize
2.28 KB

Tried the patch in #19 and it gives me edit access, but not remove access. This is because it was using $op against the host entity instead of $check_parent_op.

Am submitting a minor change to this patch to ensure that the right op is being used.

josephdpurcell’s picture

Issue tags: +Dublin2016

If any sprinters want to get some experience reviewing this, the changes from #19 to #21 can be reviewed.

idflood’s picture

We implemented this on one of our website and it resolved our issue. With workbench_moderation module, once we created a new draft the nested paragraphs where super buggy. For instance we had this structure:
- text paragraph
-- call to action paragraph

When creating the page everything worked fine. But then if on the first edit we removed the call to action and then created a new one things started to look strange. On the frontend the call to action was kind of visible but didn't had the text/url content, and on the backend the only option was to remove it but we can't edit it.

With the patch applied everything is looking good, so thanks everybody : )

I also quickly reviewed the patch and I don't see any code style error.

Tyler the Creator’s picture

Status: Needs review » Reviewed & tested by the community

I also ran into this issue today and the latest patch fixed it.

jeroen.b’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs tests

Thanks for reviewing all!
This needs tests though like I said in#12, we had too much issues with this in the past.

johnennew’s picture

Removed report that this patch causes anonymous access to private files. I think my issue was caused entirely #1453138: [D7] Private file download returns access denied, when file attached to node revision other than current

awolfey’s picture

I'm confirming #21 works. If I can get time I'll write the tests.

seanbfuller’s picture

We can also confirm that the patch in #21 solved the permission issues we were seeing with workbench / revisions.

Brauny’s picture

If your paragraphs' host entity is actually a field collection item (i.e. you have a structure like this: node->field_collection_item->paragraph), then patch 21 will work if you add the following code at the beginning of the new code in the patch:

// Fix for paragraphs nested inside field collection items. Set $entity to the node they belong to rather than the host field collection item
    if ($entity->hostEntityType() == 'field_collection_item') {
      $entity = $host_entity;
    }

You then need to apply the following patch to get field collections to work nicely with revisions:

https://www.drupal.org/files/issues/field_collection-logic_issue_with_fe...

geoffreyr’s picture

Status: Needs work » Needs review
FileSize
2.88 KB

Time to revisit this one. Something I discovered while working with RESTWS and RESTWS Entity Reference is that sometimes paragraph fields will be completely left out of an entity when the containing node is published, but has an unpublished draft.

I've uploaded a revised patch containing one minor change; removal of the ParagraphsItemEntity::isInUse() check within ParagraphsItemEntity::fetchHostDetails(). This will ensure that if it's passed in a paragraph revision ID that's used in an entity revision that isn't the most current revision, that the host entity can still be found.

This whole thing's been doing my head in so I really hope this helps someone else.

naidim’s picture

Patch #19 has been helpful. Something in patch #30 prevents proper deletion of revisions.

  • jstoller committed f750044 on 7.x-1.x authored by geoffreyr
    Issue #2594593 by ctrlADel, gadaniels72, geoffreyr, mcalabrese,...
jstoller’s picture

Status: Needs review » Fixed

Patch from #21 committed to dev.

Status: Fixed » Closed (fixed)

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