wasnt sure if anyone was interested in this...
but i wanted some more meat out of Access Permissions by User to figure out why certain users are being denied.
all this does is spell out node_access. but i think its useful ... for example for me a user didnt have view but had update/delete rights, and node_access looked fine... i didnt know image_access was allowing that users rights which this patch will spell out.

wasnt sure how to add custom function, i just have a module for that so would enable module and devel uses that custom function or can add it yourself to devel module too.

Comments

armyofda12mnkeys’s picture

whoops one line should be changed:
if (db_result($result))
return t('ALLOW: node_access lookup, rows found: '). check_plain($sql);//not caching each string since sql will be different each
else
return t('DENY: node_access lookup, no rows found: '). check_plain($sql);

btw not thinking this patch should go into module, just as needed can add easily to doublecheck your perms.

this actually helped me find a problem that was confusing me with perms...
devel was reporting wrong node access rights by user...
i saw that a anonymous user could update/delete according to devel! wahhh! but not really when actually tested that user?
realized my patch said it was image_access giving rights, basically issue was this that i posted in IRC:

"For example: in Image module you do a check for user has perms to 'edit images' and then 'edit own images' for delete/update $op.... For the super user testing access things out, he has both rights, and when devel checks node_access()'s image_access(), it cuts short after first test for 'edit images'. For another user with just 'edit own images', devel's node access will check only the current logged in user aka superuser and report falsey that user can access the node. Fix is everyone should update modules so uses 3rd arg $account in hook_access (Image doesnt), and do something like "$account = ($account!==NULL) ? $account : $user;" and use that for user checks so devel can work better. am i wrong or that makes sense?"

salvis’s picture

Status: Needs work » Active

Have you enabled the debug mode of DNA yet? Have you enabled the second block?

I believe this will tell you all there is to know about node access, and I would be interested to see an actual case where it reports false information.

If you want to pursue this, then pick one single node of yours, post its DNA debug info, pick one user with a defined set of roles, and then let's discuss what we're seeing.

BTW, your attachments don't have patch format.

armyofda12mnkeys’s picture

hey salvis,
yeh i had the DNA debug mode on. i was looking at the Access Perms by User for that node, and noticed no matter what id do for regular user, that it said they had 'yes' to update and delete ops. but in real life they did not. it made sense to me why Devel reported it that way. Cause when it checks node_access to return true/false, it passes the $account that it is checking, which is good. but in many modules, it does not use the $account param, and hence uses the global $user implicit or sometimes explicitly there, (which in turn user_access() will use) which is in most peoples cases testing the superuser. So in my case, the Image module's image_access() function just checks for user_access('edit images') and not user_access('edit images', $account) so hence why i think wrong info is reporting in Devel DNA... it checks to see if superuser has access to edit images and not the other account.

am i missing something? after changing Image module, Devel reported what drupal was doing in real life and what i thought should be correct access perms.

[whoops sorry. i just made that patch with a cygwin diff (and extra module code), maybe i did diff wrong. very simple code modifying node_access to output its info. i would have to say also that i should post small 1 line of changes to Image module as then you would see different perms show up as that is the heart of the problem and not Devel. my patch just outputs to screen the info on why user was denied or allowed]

okay, ill check that node out tomorrow and post that info. but theoretically does it not make sense the first paragraph i posted here in this post? hoping i understood what was happening, spent all day trying to figure it out )

salvis’s picture

it passes the $account that it is checking, which is good. but in many modules, it does not use the $account param, and hence uses the global $user implicit or sometimes explicitly there, (which in turn user_access() will use) which is in most peoples cases testing the superuser.

Not passing an $account but using the global $user means checking the current, which is exactly what the module wants to know. If you're user 1, it checks user 1 to decide whether to give you access, and if you're user 1234, then it checks user 1234, to decide whether to give you access.

Passing an $account is only necessary if you want to check the access that some other user would have, which is what DNA does, but most modules are only concerned with the current user.

armyofda12mnkeys’s picture

oh yes i agree, the module usually wants to know the current user, but Devel wants to know how module reacts for other users in its 'Access Perms by User' section like you said, so user_access for a module will return for current superuser, when in that case it really wants the user being inspected. In other words for any module that uses user_access without passing in $account, will have good chance of info being displayed incorrectly in Devel unless put tiny fix the module's hook_access function. I confirmed this again this morning that user shouldnt have access, and rights are set so doesnt have access, but DNA says yes unless fix module.

Just confirming, are we agreeing that DNA might display wrong info for small minority of modules, though modules which more likely that DNA wants to look at, content-type modules like Image (not Devel's fault, but cause modules dont check which to use, $user or $account in hook_access() )?

salvis’s picture

I'm beginning to understand what you're referring to.

I confirmed this again this morning that user
shouldnt have access, and rights are set so doesnt have access, but DNA
says yes unless fix module.

This doesn't help. Please pick a node, post its DNA output, and indicate where the errors are.

armyofda12mnkeys’s picture

okay here is a Image type DNA output in the attachment pics, and extra info accompanying it:
i need help debugging one more thing which i think is not correct in Access info, ill add to that at the end of this post...

So in pic 1 that is attached, u see the test1, system, contenteditor roles should have edit and update access, everyone else can only view.

in pics 2 and 3, i just included that info to show you what is going on, it doesnt really apply in my case since case i am looking at is when hook_access perms win, and not {node_access} entries......

in pic2, just making sure db got written correctly, node access is view for all, and edit/update added for those 3 roles for content_access acl module
in pic3, Devel confirms for those roles they only can access it (of course only if node_access() will end up using {node_access} entries, system can still bypass these like if user has 'administer nodes' rights or, hook_access() from module has something to say about the node's access before)

in pic4, i just add my info at the bottom of each row, i hope u dont mind as it clarifies what going on behind scenes, like what exactly gives access.
Pay attention to mbarret user, that user, has no update/delete rights in User Perms in Drupal for Images (as she is 'employee' role and they dont get 'edit [all] images' rights or 'edit own images' rights so shouldnt be able to access node,
since hook_access is being used, something is funky in there that Devel thinks allows her access, when she doesnt.

this code in drupal's Image module is useful to understand problem:

function image_access($op, $node) {//not passed $account from node_access function, 1st problem to Devel
  global $user;

  if ($op == 'create' && user_access('create images')) {
    return TRUE;
  }

  if ($op == 'update' || $op == 'delete') {
    if (user_access('edit images')) {//2nd problem for Devel, when i run Devel node access, no $account is passed to test mbarret's rights, so user_access uses what is available to determine rights. it will run as superuser, and superuser will have more rights, so can access this node. Devel recieves wrong info 
      return TRUE;
    }
    if (user_access('edit own images') && ($user->uid == $node->uid)) {//same as above
      return TRUE;
    }
  }
}

this is what content-type modules with an hook_access function like image_access should be so Devel can run correctly i think....

function image_access($op, $node, $u_account=NULL) {//need to add 3rd $account arg if module like Devel passing in info
  global $user;
  $u_account = ($u_account!==NULL) ? $u_account : $user;//correctly checks if Devel or regular module checking for perms

  if ($op == 'create' && user_access('create images', $u_account)) {
    return TRUE;
  }

  if ($op == 'update' || $op == 'delete') {
    if (user_access('edit images', $u_account)) {
      return TRUE;
    }
    if (user_access('edit own images', $u_account) && ($u_account->uid == $node->uid)) {
      return TRUE;
    }	
  }
}

now in pic 5, user rights are correct, she doesnt have access in real life, and Devel reports it that way.
on a sidenote, if she had 'edit images' rights, or (is the author of that pic and she has 'edit own images' rights), hook_access will say she is allowed access as that it will truthfully report back what she can access.
So image_access should have go through and doesnt return TRUE, by default, {node_access} checked next and shows user also doesnt have rights there.

I am having one other similar issue with devel reporting back something i think is wrong, if you want to me debug that one after this issue, specifically saying user has 'admin nodes' but user clearly doesnt. EDIT: this last new issue might be fixed. looks like maybe perms were being cached for this one. avoid this paragraph unless i followup that happens again.

Thanks for any help,
Arian Hojat

salvis’s picture

Please don't zip files. Having to do file management to read a post automatically moves that post to the "do later" (if ever) queue...

Please repost your images in plain png, jpg, or gif format, then we can look at them in the browser, and they don't take up more storage than if you hide them inside a zip file.

armyofda12mnkeys’s picture

hey salvis, sorry about that, reposted in last post.

salvis’s picture

Thank you for reposting the images. Yes, I agree that DNA's output is not reflecting the true situation, and I finally understand and agree with your analysis in #1.

This is clearly a bug in the Image module. Please report it in its queue (and refer to this thread). hook_access() has changed from D5 to D6, and the new $account parameter is not optional (http://api.drupal.org/api/function/hook_access/6). Image 6.x-1.0-alpha3 still has a number of Coder errors, and this is one of them.

I don't think DNA should be "fixed" to accommodate buggy modules, but maybe it can be "enhanced" to pin-point the bugs. What are you proposing (I can't see what's inside the zip in the OP)?

armyofda12mnkeys’s picture

StatusFileSize
new3.23 KB

okay ill let them know. Didnt realize $account was a required field anyway, thanks for pointing that out.

well possibly propose to have similar output in the 4/5 pics i attached above. see how row below the normal Devel Node Access, it says why it was Allowed. I just output the SQL for node_access as that could be useful to user to see what is allowing/rejecting for that person. or which module giving access, or maybe user is administrator. this was helpful for me. but my output can be cleaned up, maybe expandable link so that for example that long sql doesnt need to be shown until user clicks on something; or maybe stays hidden until you hit 'yes' so output can stay minimal unless user is curious about why user not given access.

Attached is the function i use to output that info in a .module file attached (actually i couldnt upload .module file, so i changed filename to .txt if thats alright, its just outputting same stuff node_access() does, nothing fancy ).

and all i did was add it to Devel Node Access, was another row (not sure why my patch wasnt working so here it is):


            while ($data = db_fetch_object($result)) {
              $account = user_load(array('uid' => $data->uid));
              $rows[] = array(theme('username', $data),
                              theme('dna_permission', node_access('view', $node, $account)),
                              theme('dna_permission', node_access('update', $node, $account)),
                              theme('dna_permission', node_access('delete', $node, $account)),
              );
              +//following lines added to devel_node_access_block() function in devel_node_access.module, didnt theme or do anything fancy to output
	      +$rows[] = array('',
		+		node_access_moreinfo('view', $node, $account),
		+		node_access_moreinfo('update', $node, $account),
		+		node_access_moreinfo('delete', $node, $account),
	       +);		
            }

salvis’s picture

There's a lot of redundancy and verbosity in your output, for example "yes" == "ALLOW", "testuser" == "user 7", but if we can streamline your output, then displaying the why in addition to the what should definitely add value to DNA.

We should probably include 'create', too, as well as a detailed evaluation of node_content_access().

What was your approach for working around Image's shortcomings?

armyofda12mnkeys’s picture

yes i am not the best at constructing sentences to display ;).
Maybe can keep everything hidden like current UI is, until click that row, then expands row underneith it with more info and if hit row again collapses... But definately an expand/collapse all link somewhere in there might help to see all at once, maybe above top row? not sure what is good UI. I can start looking at that Monday maybe.

yeh 'create' $op is good too... node_access() uses only hook_access() to check that, right?
I never understood why drupal/{node_access}table doesnt just include 'create' op, but thats another issue.
That should be simple change to devel_node_access_block ()...
+ theme('dna_permission', node_access('create', $node, $account)),

>What was your approach for working around Image's shortcomings?
i just modified Image as shown in post #7 so Devel can get correct info; but I'd prob modify it more as just realized global $user check i added not needed. Since as you said $account is not optional, i was wondering why... node_access() does the work of checking $user/$account and passing correct info into hook_access so that line i put in is redundant. so this will do i think:

function image_access($op, $node, $account) {//need to add 3rd $account arg if module like Devel passing in info

  if ($op == 'create' && user_access('create images', $account)) {// all user_access() should get $account arg that recieves automatically from node_access()
    return TRUE;
  }

  if ($op == 'update' || $op == 'delete') {
    if (user_access('edit images', $account)) {
      return TRUE;
    }
    if (user_access('edit own images', $account) && ($account->uid == $node->uid)) {
      return TRUE;
    }
  }
}
salvis’s picture

Ah, I see, you modified Image — that's out of the scope of Devel, of course.

BTW, that third parameter is not just for Devel. There are other modules that need to check access rights on behalf of other users, e.g. Subscriptions.

armyofda12mnkeys’s picture

StatusFileSize
new9.76 KB
new6.55 KB

hey salvis,

Here is addition to Devel if you want to try it/comment if should be cleaned up and added to Devel.
Any code suggestions welcome. I moved all the verbose stuff to title tag when hover over. Can take out if you want.
Checks for 'create' and verbose rows hidden. Click the row to get more info about it, jquery will unhide the moreinfo row.
Currently I added the 'expand/collapse all' functionality to just clicking Access Permissions by User heading (wasnt sure where to put +- collapse buttons).

Image attached of how it looks.

Attached is a patch for devel-6.x-1.10. I moved it out of custom function and into Devel for now on my system.

salvis’s picture

Status: Active » Needs work

Sorry, I'm short of time and can't do a full review right now, but here are a few immediate comments:

-- Coding style (indenting, etc.): Please run your file through Coder and fix the issues before creating a patch.
-- Namespace: the method name must start with devel_node_access.
-- What's the point of displaying a potentially huge "SELECT COUNT(*)" statement?
-- I haven't been able to actually try it yet, but I agree with you that expanding only one record at a time is preferable.
-- You've taken the full node_access() method from node.module, but the first few tests never apply in our context.

Keeping the code in sync with possible changes in node.module will be a challenge. It might be worth double-checking the result of node_access_moreinfo() against what node_access() returns. If we do that, then we might as well swap $user temporarily to diagnose buggy modules like Image.

BTW, we'll need patches for D5 and D7 as well, and D7 should go first, if the node access system in D7 is still unchanged (there's talk about replacing it). But let's flesh out one version first.

armyofda12mnkeys’s picture

k thanks for tips, Ill go through Coder sometime this week...

> What's the point of displaying a potentially huge "SELECT COUNT(*)" statement?
i thought that the 'node_access entries for nodes shown on this page' table is useful for debugging, but wasnt sure if those entries will be different for different people... is node_access entries same for all users, as its just looking up grants for the node? if so I can understand why not useful, esp when gets big sql. I do like knowing why exactly those entries are being returned but i can get rid of sql if it gets huge and ugly.

>You've taken the full node_access() method from node.module, but the first few tests never apply in our context.
the 'not a node' test i guess can take out. what other one(s),?

salvis’s picture

node_load() returns a node object — no need to check.
$account will not be empty, we pass it.

I'll look into the 'node_access entries for nodes shown on this page' table, but displaying raw SQL statements is only for the really desperate. This is not an option for DNA. If there's information that's not displayed, it would have to be shown in a more accessible way than as raw SQL.

(I'll be off-line for a week, so take your time...)

salvis’s picture

Status: Needs work » Closed (duplicate)

Too bad we didn't get this to fly.

However, in the meantime I've implemented something similar in #529772: Anonymous can't see a node even though DNA claims he should, so I'm marking this as a duplicate.