This is the minimal effort version of an entity access system. It is designed very very closely after the current node access system. I presume EFQ v2 gets committed first as it cleans up node_query_node_access_alter and adds significant capabilities to EFQ itself.

So, the node_access table migrates into a field handled by an entity_access module. It will a) alter EFQ v2 queries adding very similar conditions as to what node_access added before the EXISTS conversion b) will alter non-EFQ v2 SQL queries by doing the exact same subqueries as node_query_node_access_alter does right now just it will use a field_data_entity_access table instead of node_access.

Requires no Entity API change aside from adding back a query alter to EFQ v2 which is easy to do. A small change API change to the node grants hook to take an entity instead of a node.

Comments

agentrickard’s picture

@chx and I discussed this in IRC as a path-forward to three goals:

1) Allowing MongoDB all entities to use common access controls.
2) Standardizing the EFQ API by removing the special case of access control in its own table.
3) Opening the door for pluggable access control storage and handling, because we can abstract this logic to a method.

agentrickard’s picture

In this model, entity_access will control the field storage and use the access API to ask other modules "What should I store for you", similar to how {node_access} works now.

chx’s picture

There is more than just mongodb: if this is a field it just so happens it works for every entity type.

agentrickard’s picture

Agreed. Editing original.

xjm’s picture

Uh.

Damien Tournoud’s picture

So, the node_access table migrates into a field handled by an entity_access module. It will a) alter EFQ v2 queries adding very similar conditions as to what node_access added before the EXISTS conversion b) will alter non-EFQ v2 SQL queries by doing the exact same subqueries as node_query_node_access_alter does right now just it will use a field_data_entity_access table instead of node_access.

I would go one step forward and kill b) completely. If it's not an EFQ, it doesn't have access control. Period.

bojanz’s picture

So, this idea buys us simplicity, support for any entity type, language and revision support by default, which is great.

However, what happens when we add a "access per user" module, and the number of grants explodes?
We obviously don't want to load them all, together with an entity.
In fact, we might not want to load grants at all into the entity.

This field type would also have no widget and no formatter, which is also something that's a bit odd for a field.

xjm’s picture

As far as I can tell, the only reason to do this is to leverage the field system's storage and EFQ. Even having slept on it, I still can't make sense of a conceptual reason for node access to be a field. It should be determinable based on the values of fields.

I also can't see how this could possibly scale for what access control does in D7 and below. If we want to continue to support grant realms, this so-called "field" would explode. You'd have little mini tables sitting on every node.

Edit: Also, each value is not actually a single value, but a combination of a grant realm and three different grants for three different operations.

xjm’s picture

So we just discussed this a bit at BADCamp. Remaining questions:

  • The value for this field might depend on all sorts of criteria on the node, including the values of other fields. So this field's value needs to be calculated and set late in processing, after other fields'.
  • If we have an entity_access.module that provides this field type and on which access control modules depend, how does the field then get added to the appropriate entity types/bundles when an access control module is enabled? Does the module declare which entity types (and bundles??) it applies to in some hook_entity_acces_info()? Do we then have to forcibly update all bundles to include this field and follow with the entity_access_rebuild() batch operation to populate all those fields on all the existing entities?
  • And uh. What about instance? Is there only a single field and one instance of it per bundle?
  • The interaction with the revision system is also a concern. We might want to introduce a field setting to allow us to not have different values stored per revision.
fago’s picture

With #1696660: Add an entity access API for single entity access we'd have a start of entity access controllers, right now without any query-ing support. I could see us allowing them to take care of query access as well for pluggablity.

I'm not sure about basing entity-access about a field. More likely a field in the terms of the new entity field API, but not a configurable (field API) field - as we want the storage part and not the rest?
Then, while having the storage and querying support is great, but as #7 points out we don't want to load the grants upon entity-load, do we?

chx’s picture

Title: Port node access to a field » Move node access code into a plugin

OK, this is unsolvable. Let's move the node access code into a plugin without a change and that's it.

chx’s picture

Title: Move node access code into a plugin » Move node access code into a pluggable class

No need for a full blown plugin really.

moshe weitzman’s picture

An alternative is to make node_access listing API into a module and then contrib modules can just depend on that.

chx’s picture

Status: Active » Closed (duplicate)