Forums » 404 rather than 403 when accessing item without permission

RSS feed for this topic

Info

  1. I'm in the process of creating a plugin to notify admins when a new record is submitted into a workflow process. They'll receive an email with the admin URL for the record...so something like: http://www.blah.com/admin/items/show/2973.

    Obviously, that URL won't be accessible until they've logged in. Currently, however, when you get to this bit of code in application\libraries\controller\omeka\action.php (line #597):

    //Check to see whether to record exists at all
                if (!$table->checkExists($id)) {
                    throw new Omeka_Controller_Exception_404(get_class($this) . ": No record with ID # $id exists" );
                } else {
                    throw new Omeka_Controller_Exception_403('You do not have permission to access this page.');
                }

    ...it throws a 404 rather than a 403. That appears to be because of the nature of the query that's run in the $table->checkExists() call. If I look at the logs, here's what happens:

    2011-08-18T12:20:37+01:00 DEBUG (7): SELECT <code>i</code>.* FROM <code>omeka_items</code> AS <code>i</code>
     INNER JOIN
                (SELECT er_perm.relation_id as item_id
                FROM omeka_entities_relations er_perm
                INNER JOIN omeka_entities e ON e.id = er_perm.entity_id
                INNER JOIN omeka_users u ON u.entity_id = e.id
                INNER JOIN omeka_items i ON i.id = er_perm.relation_id
                LEFT JOIN omeka_entity_relationships ier ON ier.id = er_perm.relationship_id
                WHERE
                    (u.id = '11'
                    AND (ier.name = "added" OR ier.name = "modified")
                    AND er_perm.type = "Item"
                    )
                OR i.public = 1) AS <code>i_perm</code> ON i_perm.item_id = i.id WHERE (i.id = 2973) LIMIT 1
    
    2011-08-18T12:20:37+01:00 DEBUG (7): SELECT COUNT(DISTINCT(i.id)) FROM <code>omeka_items</code> AS <code>i</code>
     INNER JOIN
                (SELECT er_perm.relation_id as item_id
                FROM omeka_entities_relations er_perm
                INNER JOIN omeka_entities e ON e.id = er_perm.entity_id
                INNER JOIN omeka_users u ON u.entity_id = e.id
                INNER JOIN omeka_items i ON i.id = er_perm.relation_id
                LEFT JOIN omeka_entity_relationships ier ON ier.id = er_perm.relationship_id
                WHERE
                    (u.id = '11'
                    AND (ier.name = "added" OR ier.name = "modified")
                    AND er_perm.type = "Item"
                    )
                OR i.public = 1) AS <code>i_perm</code> ON i_perm.item_id = i.id WHERE (i.id = '2973')

    ...so it runs the query to check the permission, then runs the same query again as part of the checkExists() call. It isn't clearing any of the permission checks, in other words, so that second query fails too.

    Any clues, anyone...?

    Many thanks in advance.

  2. A URL to an admin-side items/show page should always result in a redirect to the login page if you're not currently logged in.

    As for the 404/403 issue, it's not a bug, but it does seem strange on first glance.

    By design, an anonymous user going to the public-side page for a non-public item gets a 404 error, just like for any other non-existent page. This way, there's no way for people on the public side to probe around and discover what item IDs exist. It also keeps people from seeing a potentially confusing "Forbidden" error when they likely just missed the URL.

    403 errors normally happen under different circumstances. For example, not all logged-in users have permission to go to every type of page for an item, despite being able to see it.

    I'll investigate that particular area of the code some more to see if its, as you say, uselessly doing the check twice when it will always get the same results, but regardless, the 404/403 behavior is unlikely to change.

  3. Many thanks, John.

    Are you able to point me at the bit of code which should do the redirect to the login page? It's a call to the admin side which is causing the issue, so it's possible that something I've done has prevented that redirect from working.

    If that's the case, then it's presumably doing the 404/403 check rather than the redirect, which explains why the check is behaving oddly.

  4. The code that actually performs the "logged-in" check for the admin side is in application/libraries/Omeka/Controller/Plugin/Admin.php.

    That controller plugin should be registered near the end of admin/index.php.

  5. Thanks for your help with this, John. I've now traced the issue to a bit of theme customisation that I'd done; it was redirecting the 'logged-in' check to the wrong place.

    Sorted! :)

Reply

You must log in to post.