For a project I'm working on, I need to be able to:

  • Upload a file as Admin, assigning it to a user (this is working using the "author" field at the moment), attaching it to a node (ie. using the "FileField" field type)
  • Store the file in a private directory (not accessible by public users)
  • Allow the Admin and "author" users to download the files

We've setup a test project using Drupal 7 with a FileField on a custom content type. The FileField is set to use "Private" uploads.

What seems to happen is that the files are not accessible by their path on the disk (e.g. http://sitename.com/sites/default/files/filename.pdf) but are accessible by the Drupal private file download path (e.g. http://sitename.com/system/files/filename.pdf) - even when users aren't logged in, the private file download path still allows the file to be downloaded.

What we need to do is:
Stop users who aren't logged in, and aren't the author or admin of the node, from downloading the file from the private path.

We've already got a hook_node_view() in a custom module which stops people looking at the node if they don't have permission (i.e. the $user->uid matches the $node->uid) - it's just the private file path we need to hook and validate (check the user is accurate).

Any ideas what we're doing wrong?

  • Are you using the field permission module?
    – Berdir
    Commented Jul 24, 2012 at 17:12

2 Answers 2


If the whole node should only be visible to the author, then you should either implement hook_node_access() yourself and correctly deny view access or use a content access module (e.g. Content access) to do that for you. Note that hook_node_access() won't prevent that now to show up in listings, for that you need a content access module (or implement one on your own).

Alternatively, if you just want to hide the field, you could use the Field permission module and configure it accordingly.

Both ways should be able to to this because it is something that Drupal can check, it can't know that you prevent access in hook_node_view().

  • Thanks. I'll have a look at the hook_node_access function.
    – fistameeny
    Commented Jul 24, 2012 at 21:14

Either you are missing an .htaccess file in the system/files directory, or .htaccess has been disabled there. Without it, that directory is no different from any other publicly available part of the site.

If it is missing, try creating one containing just the line Deny from all.

If such a file does exist, your server configuration is ignoring it.

Personally, I never store private files below the public webroot. If my Drupal site is at /usr/local/www/mysite, I'll put the private files in /usr/local/www/mysite-files or some such.

See also http://drupal.org/documentation/modules/file .

  • I'd prefer to store the files outside the web root, but haven't been able to work out how to do that with Drupal. Can you share any insights into the upload and download process, and what modules you use?
    – fistameeny
    Commented Jul 24, 2012 at 21:12
  • Just re-read the Drupal site from your link, and think I'm a bit clearer. I had tried to set the path to ../private, but to no avail. Will try again in the morning.
    – fistameeny
    Commented Jul 24, 2012 at 21:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.