I wanted to write a module that basically used node_access() to extend the same node access as the node owner to referenced users. But then I found this module. I wonder if we could add an option rather than have to configure all the separate grants and ops. Or if you think this is best written as a separate module.

Comments

danielb’s picture

I'm guessing you would want to dynamically update the referenced users' access upon a save/rebuild to match the node author's grants. I'm just trying to get my head around it, because at the time the node access records are being calculated during a save/rebuild a call to node_access() to check the author's access on a node won't work because the first thing that happens during a save/rebuild is the node access records get flushed.

The other complication is that when setting grants on a node that only had the default drupal grants set previously, the default grants get hosed. (Hence the setting in this module to force particular grants on the author).

I suppose you could work around it by implementing hook_node_presave, checking if there are any Node Access User Reference fields with this 'same as author' thing enabled, doing the node_access() check on the author at that point, and storing the result somewhere for use later in the save or rebuild.

I think it makes sense to put it in this module if it's going to use the 'user reference' field. The approach would also be a good addition to the author grants settings to simply 'restore' their access rather than getting the admin to choose which of view/update/delete to force onto the author and whether to grant 'view' back to 'all' (maybe not that last bit).

I would also have it so that if such options were chosen, the other options view/update/delete would be disabled by js to avoid confusion.

danielb’s picture

I'd be pretty keen on this idea, unless you can find any holes in what i've said?
I think we'd need a new database table to store the last known author grants as updated by three calls to node_access() in hook_node_presave with the follow fields: nid, view, update, delete.
I guess some other functions will be needed to maintain this table, i.e. remove records from it upon hook_node_delete, and populate the table somehow if this option is enabled after the nodes already exist (not sure how, could ask the admin to launch a batch op :(, wait for cron :(, or create an internal queue that gets processed bit-by-bit with ajax - usually my favourite way to go). If the option is disabled when nodes exist I guess we could just leave the records there until the next hook_node_presave.

danielb’s picture

I found a hole: If node access were to change for any reason (through settings, changes in node access modules, etc...) and then a rebuild is done (not a save) - the information we previously stored about the owner's access in hook_node_presave would no longer be valid.
So you're in a hook_node_access situation (different kettle of fish), or in a situation where hook_node_grants has to calculate all author's node access on all nodes on the site and let the node access system correlate that with the current user's grants.
I haven't done a module with view/update/delete grants using hook_node_access, perhaps it is high time that I did. Apparently there are some drawbacks since it doesn't kick in for node_access tagged queries.

danielb’s picture

hook_node_grants has to calculate all author's node access on all nodes on the site and let the node access system correlate that with the current user's grants.

Actually it's not that bad, we can easily cut that down to nodes that have non-empty user references with the relevant setting enabled, and of course cache the result and mark the cache as unreliable when hook_node_access_records is called.

danielb’s picture

Oh wait

There's a hook_node_access_records_alter(), we could use that and bypass all this jibber jabber, but if other modules are using that there could be a conflict...

danielb’s picture

hmm the only annoying thing is to make a successful call to node_access() at that point we'd have to write a record with node_access_write_grants(), do the stuff, and then promptly delete that record. But since that happens only during rebuild/save that shouldn't be an issue.

danielb’s picture

actually you know what... we don't even need to delete the record, that will automatically happen when node_access_acquire_grants() calls node_access_write_grants()
If that's the case why does node_access_rebuild() indiscriminately dump the whole node access table??? Thanks mr useless bit of code that makes everything harder for me

danielb’s picture

Of course doing it this way ignores any module that gives the owner any access via hook_node_access()

oh man

danielb’s picture

oh no it doesn't, not completely anyway