default rule does not show up in node_access

toniw - August 7, 2008 - 08:51
Project:Taxonomy Access Control
Version:5.x-2.x-dev
Component:Code
Category:bug report
Priority:normal
Assigned:cpugeniusmv
Status:active
Description

I have a category with a couple of terms. The category is not required, the user may leave the choice blank. In Taxonomy Access Permissions I only have specified Allow as the default rule for this category.
When I create a node with no choice made for this cat, there will appear no record in node_access for this node, resulting in no access to the node. When I then choose rebuild access permissions (admin/content/node-settings/rebuild) the records in node_access suddenly appear and access to the node is granted.
Bug? Or am I missing something?

#1

toniw - August 7, 2008 - 10:17

Just installed a fresh D5.9 with just TAC to rule out other modules causing the observed behavior.
- create category with two terms
- setup TAC permissions for anonymous user to have global default Deny and your cat default Allow
- create a node without choosing a term for your category
node_access now has:

mysql> select * from node_access;
+-----+-----+-------+------------+--------------+--------------+
| nid | gid | realm | grant_view | grant_update | grant_delete |
+-----+-----+-------+------------+--------------+--------------+
|   1 |   0 | all   |          1 |            0 |            0 |
+-----+-----+-------+------------+--------------+--------------+

goto admin/content/node-settings/rebuild to rebuild the permissions
Now node_access has:

mysql> select * from node_access;
+-----+-----+-------------+------------+--------------+--------------+
| nid | gid | realm       | grant_view | grant_update | grant_delete |
+-----+-----+-------------+------------+--------------+--------------+
|   1 |   2 | term_access |          1 |            0 |            0 |
+-----+-----+-------------+------------+--------------+--------------+

#2

cpugeniusmv - August 8, 2008 - 14:29
Category:support request» bug report
Assigned to:Anonymous» cpugeniusmv

I was able to reproduce the described behavior using your procedure in #1. This may be a bug, I'll look into it.

#3

toniw - December 22, 2008 - 23:01

I'm currently hunting this problem down since it bites my sites big time.
Initially I thought the problem was simple: in function taxonomy_access_node_access_records() is this test:

if (is_array($node->taxonomy) AND count($node->taxonomy))

As it happens $node->taxonomy is not the same at node-save time as it is while rebuilding permissions (in the above use case). If you do not select a term for the category, then $node->taxonomy is an array with one element being an empty string. While rebuilding permissions it is a zero sized array.
On node save time the if-construct takes the if part, otherwise it takes the else branch.

Once you change the if into:

if (is_array($node->taxonomy) AND count($node->taxonomy) AND $node->taxonomy[1] != "")

then the above situation is resolved.

But of course this is a way too simplistic fix. It will not work if we have more than one category, of which some might be not required.

While trying to resolve this, I stumbled on a more philosophical issue. If you do not select a value for a not required category, which access rule should be applied? Is it the default for that category? Or should the access rules for that category be totally ignored and should the default for the role be applied? Think about this for a while before answering. The consequences might be huge...

While at it, should this query:

    // Use the default for nodes with no category
    $result = db_query('SELECT n.nid, tadg.rid AS rid, tadg.grant_view AS grant_view, tadg.grant_update AS grant_update, tadg.grant_delete AS grant_delete
                       FROM {node} n INNER JOIN {term_access_defaults} tadg ON tadg.vid = 0
                       WHERE n.nid = %d', $node->nid);

not better be written like this:
    $result = db_query('SELECT rid, grant_view, grant_update, grant_delete
                       FROM {term_access_defaults}
                       WHERE vid = 0');

No need to join with the node table if we don't use any field of it...

 
 

Drupal is a registered trademark of Dries Buytaert.