I needed this for Drupal 6 but I solved it with just using .htaccess (BTW: IIS 6 using isapi_rewrite3)

RewriteEngine On

RewriteCond %{REQUEST_METHOD} ^GET$
RewriteRule ^(.*)$ /index.php?q=system/files%{REQUEST_URI} [U,L,QSA]

Comments

fletchgqc’s picture

Brilliant idea, thanks a lot! Used a modified version.

This is a simple way to produce a few protected files with CCK instead of having to use upload-related modules.

Tip for anyone debugging - change the end to [L,QSA,R=301] - this allows you to see where you're being redirected to.

highvoltage’s picture

Could you elaborate a bit more about how to go about this for drupal 6? Does it still work by file directory?

attiks’s picture

#2 It should work with D6, you only have to create a .htaccess file inside the directory with the following content

RewriteCond %{REQUEST_METHOD} ^GET$
RewriteRule ^(.*)$ /index.php?q=system/files%{REQUEST_URI} [L,QSA]

This will route all request for the files inside the directory to Drupal, so Drupal can see if a user has the appropriate permissions.

giorgio79’s picture

I tried it but the file can be still downloaded for me with an anonymous user. Even though I placed this htaccess in the specific files directory.

joachim’s picture

Same here.
The htaccess correctly sends the user via drupal to get the file (though -- it fails with Drupal in a subfolder btw).
But then there is no access control on that file in Drupal.

joachim’s picture

Ah, I've found the problem.
This redirects public files via Drupal, but you need Drupal to actually decide whether to serve the file or not.
If you're using upload module and some kind of node access system, then access will be restricted.
If like me, you're using a CCK filefield, then you need something else to actually restrict.

Something like this in a custom module:

/**
 * Implementation of hook_file_download().
 */
function MYMODULE_file_download($filepath) {
  $dirbasename = basename(dirname($filepath));
  if ($dirbasename == 'private') {
    if (user_access('download private files')) {
      return 1;
    }
    else {    
      return -1;
    }
  }
}
xjm’s picture

Interesting; tracking.

joachim’s picture

Mistake in my code above -- the hook should return NULL rather than 1 to allow access.
Here's the updated version -- though it should be noted I've not actually got this to work, as I was tangled up in trouble with htaccess at the point the client changed their mind! ;)

/**
 * Implementation of hook_file_download().
 */
function MYMODULE_file_download($filepath) {  
  // We can deny access to files of the form sites/SITE/files/private/FILENAME
  $dirbasename = basename(dirname($filepath));
  if ($dirbasename == 'private') {
    if (user_access('download private files')) {
      // Allow, or rather, say nothing and let filefield handle it.
      return NULL;
    }
    else {
      // Deny.
      return -1;
    }
  }
}
gausarts’s picture

Subscribing. Thanks

izmeez’s picture

subscribing

xjm’s picture

#3 almost works for me, but not quite. Drupal is in a subdirectory, so I have the following:

SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006
<IfModule mod_rewrite.c>
  RewriteEngine on
  RewriteCond %{REQUEST_METHOD} ^GET$
  RewriteRule ^(.*)$ /d6/index.php?q=system/files%{REQUEST_URI} [L,QSA,R=301]
</IfModule>

Paths are being rewritten to this:
/d6/index.php?q=system/files/d6/sites/default/files/subdir/filename.txt

They should be rewritten to this:
/d6/index.php?q=system/files/subdir/filename.txt

If I enter the latter URL manually, access to files is properly allowed or denied according to node access.

Edit: Here is what works for me:

SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006
<IfModule mod_rewrite.c>
  RewriteEngine on
  RewriteCond %{REQUEST_METHOD} ^GET$
  RewriteRule ^(.*)$ /d6/index.php?q=system/files/subdir/$1 [L,QSA]
</IfModule>

where subdir is the name of the specific subdirectory of files/ my protected files (and this .htaccess) are in.

ikeigenwijs’s picture

tracking

maulwuff’s picture

great!

I've been using

RewriteEngine On

RewriteCond %{REQUEST_METHOD} ^GET$
RewriteRule ^(.*)$ /index.php?q=system/files%{REQUEST_URI} [L,QSA]

using FileField and a subfolder: site/defaul/files/fileFieldFolder