The past weeks I have been working on a Drupal module that restricts access to content based on a key and a lock. Initially you would think you can use a nifty hook like hook_access or hook_nodeapi to allow the user to view the node or not. These hooks only work for the content types you provide in your module so its not really what I wanted. Drupal does not have an access hook you can use when loading any node, this is because of performance issues and its quite reasonable when you think about it. If you were to display a list of 100 nodes and each of them have to execute an access hook on every module that implements the hook, it will definitely create an overhead in the page load so Drupal does not allow this. A cleaner way to do this is to use node grants, the node grants are saved in the access table and you can use them arbitrarily to restrict access to nodes. This is how the Organic Groups module restricts access to content. So what is the problem with this? The only issue I see is performance, when you have node listings (i.e. a view), the query that pulls all the nodes will have to do a JOIN with the access table to check if the user has access to the content node or not. This table can get pretty big if we have a lot of nodes, you can potentially have nodes x users number of records.. and that you do not want.
The new approach I have been working on allows you to do have the same results but without the need of an additional table with thousands of records. You can filter any node listing on your site by rewriting the queries that are executed to the node table using the db_rewrite_sql hook (hook_db_rewrite_sql). When implementing this hook you can add JOIN and WHERE clauses to any query that is set to be rewritable. This is the best way to filter nodes across your drupal site without having a real impact on performance (considering the query doesnt take too long after you add your clauses).
This new module I have been building is called DNA Access API, it consists of assigning nodes a DNA sequence called the lock and another DNA sequence for each user called the key. The DNA is saved as a big int in the database, this integer represents a binary string (0,1,10,11,100,101, etc..). The DNA structure defines what does each bit position represent. The cool thing about this API module is that it can restrict access based on whatever you want, so this module doesnt really work by itself, you need to build a module that makes use of DNA Access API. For example, we can create a module that restricts access to nodes based on taxonomy:
Lets say we have a news site that categorizes all its content. In this site there are 5 different categories: World, Politics, Sports, Business and Entertainment. We would like the site to restrict content to users based on the taxonomy terms, so certain users can only access news from World and other users can access only content from Sports and Politics.
We can build a taxonomy access module that defines the DNA structure with the taxonomy terms, meaning that the bit positions will be as follows:
1: World, 2: Politics, 3:Sports, 4:Business, 5:Entertainment.
If we publish an article that belongs only to Sports, then the node lock would be 00100. If a user has access to Sports, Business and Entertainment, then the user key will be 00111. This means that when the user tries to access this node the access will be granted cause the the user has access to Sports and that node belongs to Sports.
This is just a small example of how to make use of the DNA Access API module. The main advantage of this over node grants or any access module is that we do not need to create additional records in the database. We only use the key and lock columns that the module creates in the node and users tables.
This module will be soon contributed to the community.