The direct path to an uploaded files does not permit download:

http://subdomain.example.com/sites/subdomain.example.com/files/private/file.pdf

The following link (subject to user having node access) permits download:

http://subdomain.example.com/system/files/private/file.pdf

However in Views under Upload: Attached files when 'Link this field to download the file' is selected, it is linked to the former, which fails.

Glad for advice on how to override this so that a private file can be downloaded from view results.

Webel

CommentFileSizeAuthor
#14 viewbefore.txt4.25 KBYesCT
#14 viewafter.txt4.29 KBYesCT
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Jody Lynn’s picture

Title: Views integration: Upload: Attached files: 'Link this field to download the file': does not use /system: with subdomain » Upload: Attached files: 'Link this field to download the file': does not work with private files
Project: Private Upload » Views (for Drupal 7)
Version: 6.x-1.0-rc2 » 6.x-2.x-dev

Sounds like a views bug to me.

dawehner’s picture

Status: Active » Postponed (maintainer needs more info)

Sry, here it works fine. Could you please try to export the view, perhaps there is something other.

webel’s picture

Now also with 6.x-2.x-dev.

This represents a confirmed security issue (not regarding core drupal security, just file and media access), so please inspect (with my sincere gratitude and encouragement in advance) a.s.a.p., and I will also respond promptly, and am actively tracking this again, thanks Webel.

An export of a very simple view of a linked node title (for a custom type Document) and Attached files as link

$view = new view;
$view->name = 'issue_private_upload';
$view->description = '';
$view->tag = '';
$view->view_php = '';
$view->base_table = 'node';
$view->is_cacheable = FALSE;
$view->api_version = 2;
$view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */
$handler = $view->new_display('default', 'Defaults', 'default');
$handler->override_option('fields', array(
  'title' => array(
    'label' => '',
    'alter' => array(
      'alter_text' => 0,
      'text' => '',
      'make_link' => 0,
      'path' => '',
      'link_class' => '',
      'alt' => '',
      'prefix' => '',
      'suffix' => '',
      'target' => '',
      'help' => '',
      'trim' => 0,
      'max_length' => '',
      'word_boundary' => 1,
      'ellipsis' => 1,
      'strip_tags' => 0,
      'html' => 0,
    ),
    'empty' => '',
    'hide_empty' => 0,
    'empty_zero' => 0,
    'link_to_node' => 1,
    'exclude' => 0,
    'id' => 'title',
    'table' => 'node',
    'field' => 'title',
    'relationship' => 'none',
  ),
  'upload_fid' => array(
    'label' => 'Download',
    'alter' => array(
      'alter_text' => 0,
      'text' => '',
      'make_link' => 0,
      'path' => '',
      'link_class' => '',
      'alt' => '',
      'prefix' => '',
      'suffix' => '',
      'target' => '',
      'help' => '',
      'trim' => 0,
      'max_length' => '',
      'word_boundary' => 1,
      'ellipsis' => 1,
      'strip_tags' => 0,
      'html' => 0,
    ),
    'empty' => '',
    'hide_empty' => 0,
    'empty_zero' => 0,
    'type' => 'separator',
    'separator' => ', ',
    'link_to_file' => 1,
    'only_listed' => 0,
    'exclude' => 0,
    'id' => 'upload_fid',
    'table' => 'node',
    'field' => 'upload_fid',
    'relationship' => 'none',
  ),
));
$handler->override_option('arguments', array(
  'nid' => array(
    'default_action' => 'empty',
    'style_plugin' => 'default_summary',
    'style_options' => array(),
    'wildcard' => 'all',
    'wildcard_substitution' => 'All',
    'title' => '',
    'breadcrumb' => '',
    'default_argument_type' => 'fixed',
    'default_argument' => '',
    'validate_type' => 'none',
    'validate_fail' => 'not found',
    'break_phrase' => 0,
    'not' => 0,
    'id' => 'nid',
    'table' => 'node',
    'field' => 'nid',
    'validate_user_argument_type' => 'uid',
    'validate_user_roles' => array(
      '2' => 0,
      '7' => 0,
      '8' => 0,
      '3' => 0,
      '6' => 0,
      '4' => 0,
      '5' => 0,
    ),
    'relationship' => 'none',
    'default_options_div_prefix' => '',
    'default_argument_user' => 0,
    'default_argument_fixed' => '',
    'default_argument_php' => '',
    'validate_argument_node_type' => array(
      'webform' => 0,
      'blog' => 0,
      'g2_entry' => 0,
      'image' => 0,
      'book' => 0,
      'component' => 0,
      'definition' => 0,
      'document' => 0,
      'external' => 0,
      'feature' => 0,
      'help' => 0,
      'issue' => 0,
      'journal' => 0,
      'linkblock' => 0,
      'methodology' => 0,
      'module' => 0,
      'moe' => 0,
      'organisation' => 0,
      'page' => 0,
      'person' => 0,
      'property' => 0,
      'publisher' => 0,
      'question' => 0,
      'requirement' => 0,
      'snippet' => 0,
      'story' => 0,
      'tip' => 0,
      'wikipedia' => 0,
    ),
    'validate_argument_node_access' => 0,
    'validate_argument_nid_type' => 'nid',
    'validate_argument_vocabulary' => array(
      '3' => 0,
      '5' => 0,
      '4' => 0,
      '2' => 0,
      '6' => 0,
      '1' => 0,
    ),
    'validate_argument_type' => 'tid',
    'validate_argument_transform' => 0,
    'validate_user_restrict_roles' => 0,
    'validate_argument_node_flag_name' => '*relationship*',
    'validate_argument_node_flag_test' => 'flaggable',
    'validate_argument_node_flag_id_type' => 'id',
    'validate_argument_user_flag_name' => '*relationship*',
    'validate_argument_user_flag_test' => 'flaggable',
    'validate_argument_user_flag_id_type' => 'id',
    'validate_argument_php' => '',
  ),
));
$handler->override_option('filters', array(
  'type' => array(
    'operator' => 'in',
    'value' => array(
      'document' => 'document',
    ),
    'group' => '0',
    'exposed' => FALSE,
    'expose' => array(
      'operator' => FALSE,
      'label' => '',
    ),
    'id' => 'type',
    'table' => 'node',
    'field' => 'type',
    'relationship' => 'none',
  ),
));
$handler->override_option('access', array(
  'type' => 'none',
));
$handler->override_option('cache', array(
  'type' => 'none',
));
$handler->override_option('items_per_page', 0);
merlinofchaos’s picture

I don't see how this could possibly be a bug in Views. Views uses the core API for creating the URL:

$file['filepath'] = file_create_url($file['filepath']);

If files are set to public it uses the direct path. If files are set to private it uses the system/files path. See http://api.drupal.org/api/function/file_create_url/6

If the private files module is not telling Drupal core that the files are private, I don't think Views can do much about it.

webel’s picture

Title: Upload: Attached files: 'Link this field to download the file': does not work with private files » Views + Private Upload: Attached files: 'Link this field to download the file': does not work with private files
Status: Postponed (maintainer needs more info) » Active

Renamed from: Upload: Attached files: 'Link this field to download the file': does not work with private files

webel’s picture

Hi merlinofchaos,

Wow, that was quick, thanks for reply.

Before I assign this back to Private Upload issues queue (i.e., excluding Views as a cause), I would like to confirm something.

You wrote:

If files are set to public it uses the direct path.

I am not 100% sure what you mean here by 'set to public'. Do you mean:

1. It is set to public download method (not a part of Private Upload module)

2. On the file attachments upload dialog in the edit form the Private Upload module's 'Private' checkbox is ticked.

As far as I understand it, Private Upload handles files under the public download method, and instead relies on .htaccess in a special folder private ../sites/www.mysite.com/files/private/.

You wrote:

If files are set to private it uses the system/files path. See http://api.drupal.org/api/function/file_create_url/6

Again, do you mean w.r.t. the Private Upload checkbox, or the private download method ?

You wrote:

If the private files module is not telling Drupal core that the files are private, I don't think Views can do much about it.

You may with this have identified this correctly as a Private Upload module problem

However could you please review the terminology and questions above, then by all means assign back to Private Upload,

many thanks,

Webel

Jody Lynn’s picture

Project: Views (for Drupal 7) » Private Upload
Version: 6.x-2.x-dev » 6.x-1.x-dev

I'm thinking there may not be a bug at all, but maybe your site is just misconfigured. webel. The private upload module is totally separate from the 'private' file system setting. There shouldn't be any paths to system/files involved.

I'm moving this issue to not take up Merlin's valuable time. I'd like to see someone else confirm a problem before looking into it.

mukhsim’s picture

This is the issue I run into:
When displaying file attachments in a view, file urls are incorrectly generated, instead of "BASEURL/system/files/private/FILENAME" the view displays "BASEURL/private/FILENAME". The url is being generated with private_upload_views_handler_filepath() (line 820). It seems that _private_upload_is_file_private() does not properly determine whether file is private or not.

My files folder is outside of webroot (../files).

Mukhsim.

webel’s picture

@Jody Lynn, thanks, am following with interest, Webel.

gabidrg’s picture

Same issue here, following this thread.

rsbecker’s picture

This probably is not a bug and really it does not matter. The solution is very simple.

You have two choices when setting up the Upload: Attached Files field in the view: Output the this field as a link, and Link this field to download the file. You should choose the former and output the field as a link and also includ the Node:Title field. On the Upload: Attached Files field set the Link Path to system/files/[upload_fid-name]. That will output the Title as a link to the file, using the right path to it, avoiding the Access Forbidden error.

webel’s picture

@rsbecker

I had indeed ''Link this field to download the file".

I changed it as recommended to "Output this field as a link".

I set the Link path: to system/files/[upload_fid-name]

I did not understand "and also includ the Node:Title field" (I of course know that a Node:Title field is, I just don't know what you mean be including it here or how/where, or why when I want to generate a link to the attached file). This is probably irrelevant to my case.

It works !

I am most grateful to rsbecker (and to all who responded) for this help, which is crucial for delivery of my current site to my client. This has been a good example of the Drupal community process working well (and I hope my own detailed description of the problem has helped invite that help).

And I can also see many other useful ways to use the flexible "Output this field as a link" facility, so thanks for alerting me to that alternative.

@rsbecker Please close on reading.

thanks,

Webel

webel’s picture

Status: Active » Closed (fixed)
YesCT’s picture

FileSize
4.29 KB
4.25 KB

I have the same trouble.

I just noticed, after having the view up for a while, that I have a view that lists the 2 most recent posts of certain criteria that have files attached, and it lists the files attached, but the link is wrong.
it lists them as files_gslc/private/SS_May_2010.pdf and it should be system/files_gslc/private/SS_May_2010.pdf
I'm using the default views field upload: attached files
Elsewhere on the site the non-private (public) ones get generated by views fine (see orange public block on left a bit down at http://goodshepherdlc.org/ )

Attached is my export before I tried the fix recommended above, and after picking to rewrite the link (and unchecking the box: link this field to download the file)

Here is a diff of the files:

me% diff viewbefore.txt viewafter.txt 
85,86c85,86
<       'make_link' => 0,
<       'path' => '',
---
>       'make_link' => 1,
>       'path' => 'system/files/private/[upload_fid-name]',
105c105
<     'link_to_file' => 1,
---
>     'link_to_file' => 0,
rimu’s picture

I got this to work eventually, but not in quite the same way.

I needed to add the Upload: Attached files field to my view (before the Upload: description field that we are primarily concerned with) to get the [upload_fid] token available. Then I could use the 'rewrite output for this field' checkbox on the Upload: description field and put in <a href="/system/files/private/[upload_fid]">[description]</a>

NickWebman’s picture

Thanks for everyone's useful advice. For me, the problem was in /admin/settings/file-system

I had it set to public instead of private.

Public - files are available using HTTP directly.
Private - files are transferred by Drupal.

mayerwin’s picture

Thanks n1ckhead, I solved my issue using your solution!

mayerwin’s picture

Actually I just noticed when running Cron:
"Private Upload will not work with file upload method set to private. Please enable Public File Transfer."

So i'll have to rewrite the output manually to make sure I don't break anything...

WorldFallz’s picture

@N1ckhead: not sure why you're using this module then. The entire purpose of this module is so you don't have to use the private download method system setting, lol.

In any case, I just committed a fix for this for my module (download_count) which supports the private_upload module. With a little effort, it should be able to be converted to a views handler for this module-- I just don't have the time to get it to it right now. The commit for the relevant code is http://drupal.org/cvs?commit=380168. It's pretty simple actually, but afaict, this module doesn't have any views 2 integration (I only saw a comment about views 1, which was never upgraded to d6, in the code).

kraguel’s picture

Same problem here using Drupal 6.16 and not using modules known to have problems with Private upload (i.e. Upload Path nor Upload Image).

I have created a content type (Download item) to publish all downloads and a simple view to list these downloadable items.

Attachment links through the view are wrong (i.e. without ".../system/...") and I still have the same problem when retrieving the content of the node directly. Enabling private downloads for the whole site (as suggested by @N1ckhead) let private downloads start working properly but "Private upload" module starts complaining as noted by @mayerwin and no way to publish public downloads. That is, the "Private upload" turns out to be useless. And further ideas?

WorldFallz’s picture

@kraguel -- read the entire thread. First, there's absolutely no reason to use private_upload with the private file system setting. Second, there's a solution above using the 'rewrite the output of this field' option in views.

rimu’s picture

Views needs to use _private_upload_create_url instead of file_create_url, if _private_upload_create_url is available.

In views/modules/upload/views_handler_field_upload_description.inc (views 6.x-2.11) I now have

  function render_link($data, $value) {
    if (!empty($this->options['link_to_file']) && $value->{$this->aliases['fid']} && $data !== NULL && $data !== '') {
      $values = $this->items[$value->{$this->aliases['fid']}];
      $this->options['alter']['make_link'] = TRUE;
      if(function_exists("_private_upload_create_url")){
          $parts = explode("/", $values->filepath);
          $values->filename = end($parts);
          $this->options['alter']['path'] = _private_upload_create_url($values);
      }else{
          $this->options['alter']['path'] = file_create_url($values->filepath);
      }
      
    }
    else {
      $this->options['alter']['make_link'] = FALSE;
    }
    return $data;
  }
rimu’s picture

Project: Private Upload » Views (for Drupal 7)
Version: 6.x-1.x-dev » 6.x-2.x-dev
Category: bug » feature
Status: Closed (fixed) » Needs review
merlinofchaos’s picture

Project: Views (for Drupal 7) » Private Upload
Version: 6.x-2.x-dev » 6.x-1.x-dev
Status: Needs review » Active

Ahh, no. It is the policy of Views' module to not add hacks specific to modules unless those modules are amongst the top contrib modules that may as well be core, such as CCK and the like.

Instead, private upload can attempt to swap out Views' handlers for its own versions that support it.

rimu’s picture

Agreed. I've been reading lots of Views documentation since my last post in this thread...

diaxpro’s picture

I read all and the solution of rewrite the link output in view not found if file is private...

File private:
system/file/private/[upload_fid-name]

File public:

system/file/[upload_fid-name]

Other solution?

rjacobs’s picture

I'd like to track this.

Please note that it appears that the workaround highlighted several times above (manually rewrite the field output in the view) seems to have some shortcomings. Namely if you upload a private file that has the same name as a public file, the system will append a number to this 2nd file (renaming it), but there is no rewrite token that correctly captures this renaming. So if you already have a public file.jpg, the second upload of file.jpg may be saved as file_0.jpg, but the rewrite solution/method above will still list the filename in the view as file.jpg (instead of the correct file_0.jpg). This leads me to believe that there are other cases where the filename may be mis-represented (and therefore incorrectly captured in the view link)

Anyway, there seem to be some cases where this solution breaks down. Sean Porter outlined more details here: #706672: Private Upload renames duplicate files, but doesn't update File: File Name in views.

It was also noted that this problem is not a bug. I suppose that is indeed true if views support is not a key expectation of private upload. I guess I don't understand enough tech specific as to how these two modules play together... but it does seem buggy IMHO.

rjacobs’s picture

The issue here: #306933: Accessing file from views implies that this problem is due to the fact that private upload only has views 1 compatibility. Furthermore, #306993 seemed to start some momentum to add views 2 support.

As stated in comment #4, the problem seems to be that while views supports the core Drupal "private files" setting, private upload requires that "public files" be set.. even though it leverages the private files concept internally.

Does that mean that this issue is a duplicate of #306993?

Cheers,
Ryan

rjacobs’s picture

Status: Active » Closed (duplicate)

Ok, a patch is now available at #306933: Accessing file from views which I believe does what merlinofchaos suggested in #24 to address this problem. As a result, I'm marking this as a duplicate... please feel free to toggle the status back if I am missing some reason why this is actually a different issue.

Ryan

rjacobs’s picture