D8, just like D7, ships only with the node access API on the query level. Other entity types get nothing.
In D7, Commerce implemented its own query alters that added the conditions needed to respect access (limiting the product type or ids to the ones the current user is allowed to see). The "grants" approach that node access takes wasn't replicated, most core people familiar with node access aren't big fans of it.
While we can easily replicate the D7 Commerce approach of individual query alters, lets see if we can implement a slightly more generic API for all of contrib to use. I've asked Damien Tournoud to comment on how he thinks this should work, since he's very familiar with node access and wrote the Commerce query alters. He thinks we should try to imitate the cache context API:
[9:45 PM] Damien Tournoud: the ACL (grants) approach works for some use-cases, and miserably fails on others
one really annoying aspect of it is that it forces you to duplicate parameters that are already on the entity, for no good reason
For example: try to express "owners can see" in a ACL
you need a to give a "uid=<owner id>" access item to every entity, and give "uid=<uid>" grant to all users
[9:53 PM] Damien Tournoud: you probably want to introduce a lot more structure in there, if you want it to be efficient
It's really similar to the caching problem. If you think of access control as keys, the problem is to efficiently generate all the possible access control keys for a particular user, and use that to match the accessible entities but to be able to efficiently generate all the possible access control keys, you need more information upfront (which is what the cache context stuff provides).
On saving the entity, you would run the access facets of the bundle, for example X and Y. Each will give you a list of values. You would end up with X = [X1, X2, X3] and Y = [Y1, Y2]
You would save all the combinations of them
X1Y1, X1Y2, X2Y1, X2Y2, X3Y1, X3Y2
On performing a query for a particular entity type, you would run all the access facets that apply to this entity type.
Here it's X, Y and Z. Each will give you a list of values.
You would expand all the subsets of them that apply to bundles of that entity type. In our case "X,Y", "Y,Z" and "Z".
That gives you a list of possible keys, and you run the query with that.
(facets being things such as uid, user role, entity bundle, etc)
Of course, access stays per bundle. The separation of keys between bundles allows us to reduce the number of possible combinations, but there might be some degenerated use cases. The best at this point would be to take the use cases of the few entity types of commerce and see if we are happy with that. The use cases will also dictate our storage decision (a field or a custom table). A field is loaded with an entity, so it's only feasible if the number of values is small.
So, the todo list goes like this:
1) Review node grants again. This article has a good explanation.
2) Review the Commerce 1.x implementation again.
3) Try to implement the new API using the Commerce 1.x use cases.
Ken Rickard also mentions he has something worth reviewing: https://twitter.com/agentrickard/status/605105820540338176
Comment | File | Size | Author |
---|---|---|---|
#13 | 2499645-13-use-query-access.patch | 3.26 KB | bojanz |
|
Comments
Comment #1
bojanz CreditAttribution: bojanz at Centarro commentedComment #2
bojanz CreditAttribution: bojanz at Centarro commentedWork has been happening in the Entity API queue: #2909970: Implement a query-level entity access API.
(Done by dawehner, sponsored by Commerce Guys)
Unfortunately, due to encountered (and now fixed) permission bugs, we were unable to finish this functionality in time for Commerce 2.0, but there's always a future release.
Comment #3
joachim CreditAttribution: joachim as a volunteer commentedThere's also an issue in core for a new entity access system.
Comment #4
drugan CreditAttribution: drugan as a volunteer commented@joachim
What the issue? Please, share if you can.
Comment #5
joachim CreditAttribution: joachim as a volunteer commentedFound it: #777578: Add an entity query access API and deprecate hook_query_ENTITY_TYPE_access_alter()
Comment #6
drugan CreditAttribution: drugan as a volunteer commentedSeems that the core issue has no any chance ever be committed. Unfortunately. So, we need to build our own DC access API. Or tweak with permissions here and there for each developer on their own.
Comment #7
Wim LeersComment #8
Wim LeersDuplicate of #2909970: Implement a query-level entity access API and #777578: Add an entity query access API and deprecate hook_query_ENTITY_TYPE_access_alter().
Comment #9
bojanz CreditAttribution: bojanz at Centarro commentedPlease don't close this. There will still be changes needed on the Commerce side (even if it's just adding the new handlers to the annotations), and they'll happen here. This issue is referenced from the Commerce roadmap.
Comment #10
bojanz CreditAttribution: bojanz at Centarro commentedWe've made good progress on #2909970: Implement a query-level entity access API. Expecting it to land within the next 2 weeks.
Comment #11
bojanz CreditAttribution: bojanz at Centarro commentedIt's time.
Comment #12
bojanz CreditAttribution: bojanz at Centarro commentedThe fourth candidate was promotions, but they don't have a bundle nor an owner, and aren't rendered anywhere, so it seems pointless.
Comment #13
bojanz CreditAttribution: bojanz at Centarro commentedInitial patch. Still needs a custom query access handler for orders, to handle the non-standard "view own" permission that we have there.
Comment #14
Wim LeersExciting!
Comment #16
bojanz CreditAttribution: bojanz at Centarro commentedAdded a custom handler for orders, and a QueryAccessSubscriber for carts. All now matching 1.x logic.
Note that stores have no "view own" permission. We can't make that assumption by default because it affects caching.
Sites that want to restrict store listings to only the user's store can implement a subscriber like this one:
Comment #17
tormiComment #19
lalop CreditAttribution: lalop commentedI use to export orders via a drupal console command.
Since I haven't a connected account while running the query I now get an empty array now.
Comment #20
Louhichi Zied CreditAttribution: Louhichi Zied commentedhello,
This could be more useful if we had the Store object inside event, like traditional symfony events which provide the event subject,
to perform a final check of :
Thx