Not entirely sure if I can classify this as a bug, but this is the scenario.

I have an ParagraphsItemEntity which has another ParagraphsItemEntity as hostEntity. This is perhaps irrelevant, but either way, the latter entity has NO host entity. The function paragraphs_paragraphs_item_access() will check the host entity's permissions, like this (on line 285 in paragraphs.module):

if (entity_access($check_parent_op, $entity->hostEntityType(), $host_entity)) { 

This will cause the code to come back again in paragraphs_paragraphs_item_access() but now for the host entity. Since there is no host entity, we end up on line 295:

// Ignore access when we don't have a host entity.
$permissions[$account->uid][$cid][$op] = PARAGRAPHS_ITEM_ACCESS_IGNORE;

The result will be returned to paragraphs_item_access() where the inline documentation states (line 194 through 197):

  // We grant access to the paragraph item if both of the following conditions are met:
  // - No modules say to deny access.
  // - At least one module says to grant access.
  // If no module specified either allow or deny, we always allow.

However, the else case is now (line 204)

else {
    // Deny access by default.
    $user_access_permission = FALSE;
  }

This is obviously contradicting.

Anyhow, it seems logic that if there is no host entity, which is possible since the latest release, the access should be allowed, since there is nothing to base your conclusions on.

PS: My ParagraphItemEntity has no host entity because it is made via my paragraph_panes module which stores the entities (ParagraphItemEntity) in the panes configuration, and does not attach them to a host entity.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Sneakyvv created an issue. See original summary.

Sneakyvv’s picture

Status: Active » Needs review
FileSize
541 bytes

Supplied patch changes default to allow (TRUE) instead of deny (FALSE).

Sneakyvv’s picture

Version: 7.x-1.0-rc4 » 7.x-1.x-dev

Patch also applies to latest dev.

jeroen.b’s picture

Status: Needs review » Postponed (maintainer needs more info)

The documentation is indeed contradicting. We changed the permissions some while ago because allowing by default is not a good idea.
It might be better to implement hook_paragraphs_item_access() in your paragraph_panes module, I don't really want to allow by default again.

If you implement the hook right you could actually check if the user has access to the panel page.
Let's say you add a file field to the paragraph type, you use the private file system.
With your patch, anyone with the URL would be able to download the file, even if they don't have access to the actual page embedding the file. That's actually the reason we changed the permissions behavior.

Sneakyvv’s picture

Status: Postponed (maintainer needs more info) » Needs review
FileSize
1.18 KB

Hi Jeroen,

I can see why you'd rather deny by default then allow, but like I said in the issue description, there's actually nothing to base your conclusions on when there's no host entity. Your code then sets the access to PARAGRAPHS_ITEM_ACCESS_IGNORE. So, it's perhaps better to also allow access in that case? In other words, when paragraphs itself has concluded that it cannot allow or deny based on the host entity (and thus sets access to ignore) ànd no other module explicitly allows nor denies access, access is allowed.
The difference is that "the default" is still to deny, except when there's no host entity (and no other module denies access).

I've attached a new patch, which also corrects the contradicting documentation.

Status: Needs review » Needs work

The last submitted patch, 5: paragraphs-allow_access_for_explicit_ignore-2649608-5.patch, failed testing.

Sneakyvv’s picture

I seem to be still recovering from my holiday...
This patch has correct paths.

Sneakyvv’s picture

Status: Needs work » Needs review
Sneakyvv’s picture

Title: paragraphs_item_access should ALLOW access by default » paragraphs_item_access should ALLOW access for explicit PARAGRAPHS_ITEM_ACCESS_IGNORE
Sneakyvv’s picture

The previous patch didn't work because PARAGRAPHS_ITEM_ACCESS_IGNORE is NULL. Since module_invoke_all is ignoring NULL as a result from any hook, you can't check if the return value of the paragraphs_item_access hook is PARAGRAPHS_ITEM_ACCESS_IGNORE, simply because module_invoke_all is not putting it in the result array.

Therefore this patch has been altered to change the value of the constant to 'ignore' as well. The constant is not being checked in paragraphs module for its value. Of course, other modules might, but then again they shouldn't. They should always check against the constant, not the value.

Finally, I noticed that paragraphs is passing PARAGRAPHS_ITEM_ACCESS_IGNORE twice, while the documentation states it wants to deny. I changed the return values to PARAGRAPHS_ITEM_ACCESS_DENY for those cases.

PS: @jeroen.b, I would gladly implement my own hook_paragraphs_item_access, and check the access against the panel or pane the paragraph item is in (if I understand your suggestion correctly), but then I would need to figure out how ctools works, and it's not the best documented module out there. At least not what I can find about it...
So, if you could offer some insight, it would be greatly appreciated.

Status: Needs review » Needs work

The last submitted patch, 10: paragraphs-allow_access_for_explicit_ignore-2649608-10.patch, failed testing.

couloir007’s picture

I have entityref fields in a paragraph within a paragraph, which worked fine when initially adding a paragraph item and the paragraph entity_id was null. Once I saved the content I could not add more entityref items to existing paragraphs because the entitity_id was set, denying access. This patch solved it. I posted the Ajax Error below which may be useful to someone searching the same issue. Thank you.

An AJAX HTTP error occurred.HTTP Result Code: 403
Debugging information follows.
Path: http://MyURL/index.php?q=entityreference/autocomplete/single/field_ngss_entref/paragraphs_item/ngss_tags/521
StatusText: error
ResponseText: No Access Permitted | MyWebsite
@import url("http://MyURL/modules/system/system.base.css?ojl3xn");
@import url("http://MyURL/modules/system/system.menus.css?ojl3xn");
@import url("http://MyURL/modules/system/system.messages.css?ojl3xn");
@import url("http://MyURL/modules/system/system.theme.css?ojl3xn");
@import url("http://MyURL/misc/ui/jquery.ui.core.css?ojl3xn");
@import url("http://MyURL/misc/ui/jquery.ui.theme.css?ojl3xn");
@import url("http://MyURL/misc/ui/jquery.ui.button.css?ojl3xn");
@import url("http://MyURL/misc/ui/jquery.ui.resizable.css?ojl3xn");
@import url("http://MyURL/misc/ui/jquery.ui.dialog.css?ojl3xn");
@import url("http://MyURL/misc/ui/jquery.ui.datepicker.css?ojl3xn");
@import url("http://MyURL/modules/contextual/contextual.css?ojl3xn");
@import url("http://MyURL/misc/ui/jquery.ui.accordion.css?ojl3xn");
@import url("http://MyURL/modules/comment/comment.css?ojl3xn");
@import url("http://MyURL/sites/all/modules/contrib/date/date_api/date.css?ojl3xn");
@import url("http://MyURL/sites/all/modules/contrib/date/date_popup/themes/datepicker.1.7.css?ojl3xn");
@import url("http://MyURL/sites/all/modules/contrib/date/date_repeat_field/date_repeat_field.css?ojl3xn");
@import url("http://MyURL/modules/field/theme/field.css?ojl3xn");
@import url("http://MyURL/sites/all/modules/contrib/kaltura/style/kaltura.css?ojl3xn");
@import url("http://MyURL/sites/all/modules/contrib/logintoboggan/logintoboggan.css?ojl3xn");
@import url("http://MyURL/sites/all/modules/contrib/mollom/mollom.css?ojl3xn");
@import url("http://MyURL/modules/node/node.css?ojl3xn");
@import url("http://MyURL/modules/user/user.css?ojl3xn");
@import url("http://MyURL/sites/all/modules/custom/webform_context/webform_context.css?ojl3xn");
@import url("http://MyURL/sites/all/modules/contrib/extlink/extlink.css?ojl3xn");...