Closed (fixed)
Project:
Commerce Core
Version:
7.x-1.x-dev
Component:
Order
Priority:
Normal
Category:
Feature request
Assigned:
Unassigned
Issue tags:
Reporter:
Created:
13 Apr 2012 at 10:31 UTC
Updated:
4 Oct 2015 at 01:04 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #1
joachim commentedThe chain of access for commerce entities is fairly complex, so here's a summary:
- commerce_order_ui_menu() defines the path /user/X/orders/Y with access callback commerce_order_customer_order_view_access()
- commerce_order_customer_order_view_access() calls the entity access callback, commerce_order_access()
- commerce_order_access() calls the generic access helper, commerce_entity_access()
- for view operations, this constructs an access query based on the entity, which relies on Database API invoking hook_query_ACCESS_TAG_alter(). For orders, this is hook_query_commerce_order_access_alter().
- commerce order's implementation of this hook, commerce_order_query_commerce_order_access_alter(), calls a generic implementation back in commerce module, commerce_entity_access_query_alter()
- commerce_entity_access_query_alter() checks entity type and user access permissions for the entity.
Comment #2
rszrama commentedAnd then to finish off the chain, commerce_entity_access_query_alter() builds an OR conditions array that you can alter for Orders using hook_commerce_entity_access_condition_commerce_order_alter(). Note that restricting access is different from granting access. To restrict access you'll actually need to alter out existing conditions that would otherwise grant the user access to view the order.
While there is no user interface for building this feature, which would be out of scope for Commerce itself anyways, it does seem the API supports what you need. I'm going to mark this works as designed, but feel free to post follow-up questions.
Comment #3
bennybobw commentedI'm a bit fuzzy on this. I'm trying to set order access based on a field value on the order (a reference to a user profile, like in this issue https://drupal.org/node/1434610).
This is how I've implemented it -- I've had to use 2 hooks. hook_query_commerce_order_access_alter and hook_commerce_entity_access_condition_commerce_order_alter.
Inside the condition hook, I add the field condition, but I don't have access to the query there, so I can't add the join. However, in the query hook, I don't necessarily know which $query->conditions() contains the access condition. For instance, one of my views nests the access condition inside of its own condition. So in the condition hook, I have to add the condition and in the query hook I add the condition.
Not sure if this is the best way to do it, but it's the only way I could figure it out.
Comment #4
rszrama commentedIf what you've done works, there probably isn't any reason to change it. However, what you could do instead is just actually include the data in your condition that you'd be joining to. In other words, nothing prevents you in your query from having a condition that compares 1 and 2. If 1 is your target_id and 2 is your $profile->pid, it will be FALSE, no query level join required.
See for example commerce_cart_commerce_entity_access_condition_commerce_order_alter(), which restricts an anonymous user's access to only view orders whose IDs are present in the user's session:
Comment #5
mihai_brb commentedJust to summarize:
View access
+ can be granted by implementing hook_commerce_entity_access_condition_commerce_order_alter and adding a condition in the OR chain that will satisfy the query
Edit/Delete access
+ can be granted by implementing hook_commerce_entity_access
When implementing "view" access alter, I find it a little inconvenient that:
- the view page callback checks for entity access but also user_access('access administration pages')
- the edit page callback only checks for entity access
If for example I would like to grant access to a site manager to view certain orders, I would also have to add access to administration pages?
Isn't sufficient to check for entity access in the order view page callback?
Moreover, in "commerce_entity_access", it would ease the pain of getting the entity ID that is currently issued for viewed access if we would have the entity object, or at least entity_id or as metadata in context.
Thanks,
Mihai
Comment #6
mihai_brb commentedAdded a patch that adds the entity as Metadata and passes the entity in context to hook_commerce_entity_access_condition().
This should fix the problem of not having the entity issued for view access.
Comment #12
mglamanComment #13
mglamanAdjusting title to be more fitting of patch in #6. More context is always better in my opinion.
Comment #15
rszrama commentedWorks for me! Committed.