There is a bug in user.module that admins get a "page not found" message for blocked accounts, even though they should be allowed to see them. I also think that blocked accounts should return a 403 for non-admins, not a 404.
The attached patch fixes these problems.
However, in experimenting with possible solutions I uncovered a weird menu issue. Tracker.module and statistics.module register "user/N/track". Contact registers a "user/N/contact" tab. These tabs are dynamic and appear for all paths with the format "user/N". If "user/N" decides to throw a 403 or 404 then the other tabs will still appear, as the menu system hasn't changed its location.
You can see this in action at http://drupal.org/user/15396. This account is blocked.
The cause is that the 403/404 checks for the tabs are each done in their own menu handler (invoking drupal_not_found() or drupal_access_denied()), and not in hook_menu. However moving the checks to hook_menu would mean duplicating this check (and the queries) across several modules, and we'd have to avoid the menu falling down from "user/X/Y" to "user" (which has its own tabs, if you're an anonymous user) if the menu handler is not registered.
Note that if custom 403/404 pages are used, then no tabs will show up as menu_set_location() is called to move to the custom 403/404 page, which is located somewhere else on the menu tree.
This is further amplified by the fact that the access rules for the different tabs are inconsistent (some don't respect admin overrides, some don't respect blocked status).
We can fix this problem by calling menu_set_location() with some dummy location in drupal_not_found() and drupal_access_denied(), thus ensuring we're somewhere else in the menu tree. In that case, the tabs won't appear for any 403/404. If we make the access rules across the different tabs consistent, then what you see in the UI (no tabs) will match the access rules.
What do you guys think?
| Comment | File | Size | Author |
|---|---|---|---|
| #10 | user.404.2.patch | 6.12 KB | merlinofchaos |
| #8 | user.404.patch | 5.8 KB | Steven |
| user.blocked.patch | 1.53 KB | Steven |
Comments
Comment #1
killes@www.drop.org commentedI'd like this to get fixed, but I think your patch is incomplete for technical reasons:
***** CVS exited normally with code 1 *****
Comment #2
Steven commentedThe patch only fixes the 403/404 and does not address the tabs issue yet, as I was not sure what the best approach was. The "*** CVS" thing is normal.
Comment #3
killes@www.drop.org commentedDoesn't apply anymore.
Comment #4
killes@www.drop.org commentedChanging status.
I think the solution proposed makes sense.
Comment #5
junyor commentedSteven: Just to clarify, if a user has admin users permission and they get a blocked user page, will they get an Edit tab? That's what I'd like to see.
Additionally, would it be appropriate to say "This user has been blocked" rather than "Access denied"?
Comment #6
jose reyero commentedPlease, see http://drupal.org/node/53348
Comment #7
Steven commentedActually this has nothing at all to do with the fact that user entries no longer exist. It is purely about menu system and 404/403 handling.
Comment #8
Steven commentedIt's time to sort this one out. The attached patch fixes two things:
Comment #9
merlinofchaos commentedThis patch breaks the 404 an administrator receives when looking at an invalid UID.
Previously, when going to a random user/XXX where XXX is out of range, Drupal would present a 404.
Now it presents a user profile page with no info.
Comment #10
merlinofchaos commentedOk, the attached patch fixes that.
The problem was that the access check in hook_menu was not adding a menu handler at all if $user did not exist, which meant it fell back to the default 'user' hook which still went through to user_view.
Simply adding an if in user_view() corrects that problem.
Otherwise, the patch is +1.
(The only substantive difference between my patch and Steven's is:
> + if ($account === FALSE) {
> + return drupal_not_found();
> + }
Comment #11
killes@www.drop.org commentedapplied
Comment #12
bart jansens commentedUsing menu_set_active_item('#') changes $_GET['q'], which probably isn't what we want..
When you get a 403 with a login block on the side, after you log in, you get a 404 error instead of the real content because you are redirected to the wrong URL (%23 which is an urlencoded #).
Comment #13
killes@www.drop.org commentedlet's continue here: http://drupal.org/node/55869
Comment #14
(not verified) commented