Hello,

I am confused about how to use IMCE with the private file system. What is the best way to use IMCE with the private file system?

I cannot upload files into nodes with the IMCE browser unless I uncheck the box "Disable serving of private files" in the 'Common Settings' of IMCE's configuration page. And if this setting is unchecked, can anyone with the URL access those files? This somewhat defeats the purpose of the private file system, doesn't it?!?

Are there modules I could use to restrict access to those files? Or do I not understand this correctly?

Thanks for your help for a newbie. :)
Andre

Comments

IMCE does not apply any restriction while serving private files. You need a custom module for that. I don't know of any.

This only applies to when you have multiple untrustworthy users using IMCE, while they use IMCE, right? I mean, when the node displays, the image still gets served by Drupal via the private route if I understand this correctly. And if you trust all of your IMCE users, then who cares how the file gets served to the file browser. Am I wrong?

@rconstantine, it's about how you want to restrict access to the site files. If you don't want any restrictions, there is no reason to use the private file system. Public files are served by apache which is way faster than serving private files by PHP.

OTH, if you want some kind of restriction, you will need a custom module that prevents serving of files by applying a set of predefined rules.

Hi,
I'm not sure if this is the right thread, but I have a matter using IMCE and private file system. Module seems work well, nevertheless when Users click on a file to download the browser doesn't show the correct filename in the downloading windows. For instance, Firefox 7.01 shows a random mix of letters (containing file extension); IE9 shows IP or name server. This behaviour doesn't appear using public file system: filename showed is correct.
Thanks in advance.
Claudio, Italy.

Hi,
I just solved the issue described above enabling rewrite rules and clean-urls. I'm not skilled enough to understand the reason; I hope this may help someone.

If you don't find any module #1 is saying, this worked fine for me:

Edit imce.module file and change:

function imce_file_download($uri) {
  $serve = file_uri_scheme($uri) == 'private' && !variable_get('imce_settings_disable_private', 1) &&  file_exists($uri) && strpos(basename($uri), '.');
  if ($serve) {
    return array(
      'Content-type' => file_get_mimetype($uri),
      'Content-Length' => filesize($uri),
    );
  }
}

to this that will limit private file access to authenticated users (role ID = 2):

function imce_file_download($uri) {
  $serve = file_uri_scheme($uri) == 'private' && !variable_get('imce_settings_disable_private', 1) &&  file_exists($uri) && strpos(basename($uri), '.');
  if ($serve) {
global $user;
if (array_key_exists('2', $user->roles)) {
return array(
  'Content-type' => file_get_mimetype($uri),
  'Content-Length' => filesize($uri),
);
}
  }
}

In #266549: directory protection from leeching there is a more interesting patch, but for IMCE in Drupal 6.

Would it be possible for IMCE to call something to check? We could then put hooks into nopremium and similar modules for IMCE.

hook_imce_can_i_display_this_image($user, $page, $image);

The add other modules can then decide based on the user or page or image.

@petrex, you don't need IMCE to define a hook for file access. You can use hook_file_download().

#6 worked to stop anonymous access, but not to control specific user access - one user could see another users files.

The test was to:
1 - log in as user A, double click a file - file opens in new tab showing URL - copy URL
2 - logout - get access denied when trying to access the URL - no anonymous access
3- log in as user B - access to the url is granted

@yoclaudio, thanks for this workaround - a good start, but I wonder if it's possible to improve the workaround for individual user access?
It may not be a massive problem, as it's unlikely user B will know specific URL's for user A's files.
However we know from this test it is not as secure as we'd like.

Any thoughts?

I changed some of the code of #6 to restrict access to anyone except the owner of the private file.

ORIGINAL CODE

function imce_file_download($uri) {
  $serve = file_uri_scheme($uri) == 'private' && !variable_get('imce_settings_disable_private', 1) &&  file_exists($uri) && strpos(basename($uri), '.');
  if ($serve) {
    return array(
      'Content-type' => file_get_mimetype($uri),
      'Content-Length' => filesize($uri),
    );
  }
}

MODIFIED CODE

function imce_file_download($uri) {
  $serve = file_uri_scheme($uri) == 'private' && !variable_get('imce_settings_disable_private', 1) &&  file_exists($uri) && strpos(basename($uri), '.');
  if ($serve) {
  global $user;
  $file_uid = db_query("SELECT uid FROM {file_managed} WHERE uri=:uri",
                        array(':uri' => $uri))->fetchField();
  if ($user->uid == $file_uid) {
  return array(
    'Content-type' => file_get_mimetype($uri),
    'Content-Length' => filesize($uri),
  );
  }
  else return -1;
  }
}

Remember that we shouldn't modify modules' code!

Hope this will help.

Hi,
as romainj said modifying of modules' code is not good idea, so you can add this hook in your own module.

I needed to add some restrictions to IMCE (version 6 of module, but it should be the same for 7) files, and this is my solution:

  1. Uncheck "Disable serving of private files" in Common Settings of IMCE module.
  2. Add hook_file_download() hook into your module.

<?php
/**
* Implementation of hook_file_download().
*/
function my_module_file_download($filepath) {
   
$filepath = file_create_path($filepath);
   
// Check permissions only for IMCE files
   
$result = db_query("SELECT f.* FROM {files} f INNER JOIN {imce_files} i ON f.fid = i.fid WHERE filepath = '%s'", $filepath);
    global
$user;
    while (
$file = db_fetch_object($result)) {
      if (
$filepath !== $file->filepath) {
       
// Since some database servers sometimes use a case-insensitive
        // comparison by default, double check that the filename is an exact
        // match.
       
continue;
      }
     
// Here you can add your own rules for accessing files.
      // For example: allow access only to files that user had uploaded
     
if ($file->uid == $user->uid)
      {
        return array(
         
'Content-Type: ' . $file->filemime,
         
'Content-Length: ' . $file->filesize,
        );
      }
      else {
        return -
1;
      }
    }
}
?>

p.s: Inspired by drupal core Upload module.