- Issue created by @mlncn
- 🇺🇸United States mlncn Minneapolis, MN, USA
(anything based on this approach would generally be sub-optimal performance-wise, like a giant
IN
statement rather than a beautifully crafted set of joins, but it should still work…) - 🇩🇪Germany jurgenhaas Gottmadingen
What's required to alter the access on views results is an event or a hook that's being dispatched by the views module so that other modules can alter the results. If there isn't an API for that, ECA won't be able to get involved. I'm not sure from top of my head if anything like that already exists? How would you alter the access on views results when you would do that with custom code in PHP?
- 🇺🇸United States mlncn Minneapolis, MN, USA
I had been thinking of doing this in https://api.drupal.org/api/drupal/core%21modules%21node%21node.module/fu...
But the recommended/correct way for intervening for content access that works for queries is via giving grants to users and defining the
https://api.drupal.org/api/drupal/core%21modules%21node%21node.api.php/f...
https://api.drupal.org/api/drupal/core%21modules%21node%21node.api.php/f...
And on further consideration those hooks are what we would want to make available to ECA.
- 🇺🇸United States mlncn Minneapolis, MN, USA
A fairly simple example, tested and working.
ECA could definitely do this, it would be a completely separate capability from ECA Access (which uses hook_node_access), so i withdraw/redirect the initial request; Drupal basically has two different systems, and i think ECA could plug into this one as well. Maybe an eca_node_access module.
/** * @file Access hooks for advocates. */ use Drupal\Core\Session\AccountInterface; use Drupal\node\NodeInterface; /** * Implements hook_node_grants(). */ function hw_advocate_node_grants(AccountInterface $account, $operations) { $grants = []; if ($account->hasPermission('advocate for clients')) { $household_nodes = \Drupal::entityTypeManager()->getStorage('node')->loadByProperties( [ 'type' => 'household', 'field_advocate' => $account->id(), ] ); foreach ($household_nodes as $node) { $grants['hw_advocate'][] = $node->id(); } } return $grants; } /** * Implements hook_node_access_records(). */ function hw_advocate_node_access_records(NodeInterface $node) { $grants = []; if ($node->bundle() === 'household') { $grants[] = [ 'realm' => 'hw_advocate', 'gid' => $node->id(), 'grant_view' => 1, // TRUE, but docs say 1 'grant_update' => 1, 'grant_delete' => 0, ]; } return $grants; }
- 🇩🇪Germany jurgenhaas Gottmadingen
That sounds like a good idea to add support for
hook_node_grants
andhook_node_access_records
, maybe also forhook_node_grants_alter
andhook_node_access_records_alter
.It's just unfortunate, that this is only available for nodes, and not for entities in general.
However, I'd say this functionality belongs to the eca_access sub-module.
- 🇺🇸United States mlncn Minneapolis, MN, USA
Sorry, pushed what i've got as a start, just trying to set the stage for what is needed, but it's erroring immediately:
There must be only one distinct plugin definition for each system event. Affected system event : eca_access.entity
I think i'm really struggling with trying to do it in the ECA Access module when the ECA way of doing different events in one module seems to involve a ton of conditional logic that i'm trying to avoid.
- 🇩🇪Germany jurgenhaas Gottmadingen
This looks indeed pretty complicated and when I read through all the grant API documentation, things suddenly started to get familiar. I thought, haven't we done that somewhere already? And yes, we did.
There is the content_access → module which implements the node grant hooks already. And with the eca_content_access → module, we're allowing ECA to either grant or revoke access.
The only limitation is that content_access doesn't support D11 yet, but the patch is available and RTBC'd, so let's hope it's landing soon.
- 🇺🇸United States mlncn Minneapolis, MN, USA
Finally back to this, and i don't think ECA Content Access is what i am looking for.
First, there should not be a need for the Content Access contrib module.
Second, and most important, it lets the access for a role to be changed from the configured Content Access default for an individual node, but it does not allow varying the access per user account.
Third, to do things in the way node access works best, we really should be able to set grants on the account and grants on a node. Content access is using node_grants but not exposing the full flexibility. (Also, though i don't know if it matters, it is not defining a realm at all.)
Here is the underlying method eca_content_access uses, from NodeAccessControlHandler:
* @param \Drupal\node\NodeInterface $node * The node whose grants are being written. * @param array $grants * A list of grants to write. Each grant is an array that must contain the * following keys: realm, gid, grant_view, grant_update, grant_delete. * The realm is specified by a particular module; the gid is as well, and * is a module-defined id to define grant privileges. each grant_* field * is a boolean value. * @param string $realm * (optional) If provided, read/write grants for that realm only. Defaults * to NULL. * @param bool $delete * (optional) If false, does not delete records. This is only for * optimization purposes, and assumes the caller has already performed a * mass delete of some form. Defaults to TRUE. */ public function write(NodeInterface $node, array $grants, $realm = NULL, $delete = TRUE);
Used here:
if ($this->updateSettings($bundleSettings, $this->configuration['operation'], $this->configuration['role'])) { $this->database->merge('content_access') ->keys(['nid'], [$entity->id()]) ->fields(['settings' => json_encode($bundleSettings)]) ->execute(); /** * @var \Drupal\node\NodeAccessControlHandler $controllHandler */ $controllHandler = $this->entityTypeManager->getAccessControlHandler('node'); // Apply new settings. $grants = $controllHandler->acquireGrants($entity); $this->grantStorage->write($entity, $grants);
- 🇺🇸United States mlncn Minneapolis, MN, USA
Active branch does everything… except token replacement for the actions! Something obvious i am sure but way out of time to work on this for a while.
- 🇩🇪Germany jurgenhaas Gottmadingen
Left a few comments in one of the action plugins with regard to handling config values and tokens. Before a full review please ensure that tests are green. Then please set the issue status to "Needs review" so that we get notified accordingly.
- 🇺🇸United States mlncn Minneapolis, MN, USA
17 | ERROR | [ ] Parameter $account is not described in comment | | (Drupal.Commenting.FunctionComment.ParamMissingDefinition) 20 | ERROR | [ ] Doc comment for parameter $account; does not match actual | | variable name $account | | (Drupal.Commenting.FunctionComment.ParamNameNoMatch)
/** * Triggers gathering grants. * * @param \Drupal\Core\Session\AccountInterface $account; * The user account. */ public function grants(AccountInterface $account) {
Is PHPCS drunk?