The current Drupal core defines two content types, page and story. Anyone with 'access content' permissions is able to see both the nodes these content types define, as well as the teasers that they provide.
When creating modules that define new content types, the developer can set 'view' permissions inside hook_access(). However, this hook is not called when rendering teasers, and as a result, users who do not have permissions to view the node itself (but do have 'access content' permissions), will still be able to view the teaser for the node. This can be a risk to the security of the data on your site, as users may be able to see content of nodes that they shouldn't be able to see.
Who this module is for
This module is useful for two groups of people:
- Module developers whose modules define custom content types in which the teaser shows even though permissions haven't been granted to the user in hook_access().
- Site administrators whose sites that are showing teasers for custom content types even though the user doesn't have permissions to view the content type.
Drupal has a two step system for determining whether a user has access to the four core actions performed on nodes: create, edit, delete and view. The first step is in hook_access(), which defines access permissions for all nodes of the entire node type. This hook is called each time a user tries to perform one of the four core actions on a node. If no value is returned from this hook, the system then goes on to look at the grant system, which determines whether a user can perform one of the four core actions on a per node basis. This grants system is made up of two hooks: hook_node_access_records(), which is called whenever a node is saved, and states the circumstances under which a user can perform any of the four core actions on it, and hook_node_grants(), which is called whenever a user tries to perform any of those four core actions on a node, in the case that no value was returned from hook_access().
Now where the problem arises is that calling hook_access() every time a teaser is rendered is fairly resource intensive. But calling on the grants system is much less intensive (based on how the Drupal query has been constructed). So teasers are only compared against the grants system, not hook_access(). As such, if hook_node_access_records() and hook_node_grants() are not properly defined in a module that defines a custom node type, the teaser will render, regardless of whether a user returns a value for 'view' in hook_access().
The ideal solution to the problem of teasers being rendered when they shouldn't be, is to implement hook_node_access_records() and hook_node_grants(), which is the proper Drupal method. However, these can be very difficult to understand, and there seems to be a lack of information on how to do this properly, so it can be a difficult task for many module builders. Which is where the other solution comes in:
The Less Ideal Solution
This module was created as a stop gap measure to deal with the problem. This module calls hook_access upon the rendering of each teaser and checks if the user has the permission to view the node. If they don't have permission to view the node in question, all content is stripped from the teaser, and a message is provided informing the user that they don't have permissions to view that teaser. This works for all teasers everywhere, all the time.
Issues with this module
- There is no way to prevent the node from rendering in the first place. So instead of the teaser not rendering at all, which would be preferable, the space where the teaser should have been is rendered with a message informing them that they do not have permissions to view the information contained (not as ideal, but still a solution to the initial problem).
- Be warned that installing this module will place an additional burden on your server when rendering pages containing teasers, as it has to add a permissions check for each teaser it renders.
- This module works right away upon installation. Upon installation, teasers will be suppressed without any need for configuration.
- Users are shown the message "You do not have permission to view this item" for any teasers that have been suppressed. To change this message, navigate to admin/settings/suppress_teasers, and set your message there.
- July 6, 2009
- As requested in my issue queue, I added a message that displays when the user does not have permission to see the node, as well as the ability to change that message at admin/settings/suppress_teasers.
- Japanese translation for default message added