Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
In 7.x-2.0-beta-1, file_entity_file_download() changed its behavior and returns -1 instead of NULL if $file->fid is not empty and if file_entity_access('view', $file) returns FALSE. Shouldn't it still return NULL in this case, so that other modules can grant access?
Comment | File | Size | Author |
---|---|---|---|
#1 | Fix_file_entity_file_download-2351691-1.patch | 290 bytes | morenstrat |
Comments
Comment #1
morenstratPatch attached.
Comment #2
morenstratComment #3
wmfinck CreditAttribution: wmfinck commentedThank you for this patch, which just bailed me out of hours of heartache.
Comment #4
FunkMonkey CreditAttribution: FunkMonkey commentedThanks so much! This issue caused me major problems today when I upgraded Commons to 3.18. We use FileDepot and it completely prevented access to hundreds of non-admin users to any file on our system. The patch took care of it. Marking as Major since this is a huge issue on a site like ours. Marking RTBC as the patch worked for me and apparently @wmfinck.
I wonder if it was changed to fix some other issue though?!
Thanks again @dunix.
Comment #5
aaron CreditAttribution: aaron commentedComment #8
aaron CreditAttribution: aaron commentedCommitted to http://drupalcode.org/project/file_entity.git/commit/5b5e5a5.
Comment #10
znerol CreditAttribution: znerol commentedThis patch reverts #2164527: Cannot deny access to private files. My understanding is that if you want to server private files, then you should grant View private files permission to the roles in question.
Comment #11
morenstratI think we have to differentiate between downloading and viewing files. The problem is that files should often inherit download permissions from their parent entity, e.g. a node. If you have the permisson to view a node, you should also be able to download the (private) files that are attached to it. With file_entity_file_download() returning -1 instead of NULL, this is not possible.
Maybe the problem in #2164527: Cannot deny access to private files is that some other module is granting access? file_download() only grants download access if some module returns headers, so returning NULL in file_entity_file_download() should be sufficient for denying download access, given that no other module returns any headers.
Comment #12
znerol CreditAttribution: znerol commentedfile_file_download always grants access and returns the headers for files linked from file fields. This is expected behavior and not caused by some strange core/contrib module.
Comment #13
morenstratfile_file_download does not always grant access. It calls file_get_file_references() to find out if you have access to an entity that references the file field and then field_access() to find out if you have access to the file field itself.
Comment #14
znerol CreditAttribution: znerol commentedWell, let's rephrase that.
file_file_download
first determines if the file to be downloaded is controlled by the file module, i.e. is referenced from a file field. If it is not, then it returnsNULL
. If it is it continues with checking permissions and if the user has access to the field, then it allows the download by returning the headers. This is what I meant in #12, sorry for the sloppy comment.The important thing to note is the sentence in hook_file_download documentation for the return value:
It is expected behavior that some module claims ownership of a file download and that it returns headers from its
hook_file_download
implementation if the user has access according to the permissions respected by that module. So if the core file module decides that according to field access a file should be downloadable by a user, then the file entity module only can prevent that by returning-1
from itshook_file_download
.Thus
hook_file_download
needs to return-1
for private files when users are lacking the View private files permission. ReturningNULL
in that case will not have any effect.Comment #15
silkogelman CreditAttribution: silkogelman commentedThanks for this!
It solved this usecase for me:
private file access based on Organic Group membership with og_access and og_field_access.
Comment #16
morenstratI think the expected behavior is that modules implementing
hook_file_download()
play nice with each other. Iffile_entity_file_download()
returns -1, it does not play nice because it takes over all files and does not allow other modules - such as the core file module - to grant access and breaks their access logic.Granting the View private files permission is not a solution. It does not allow the other modules to keep their access logic because it grants access to all private files. I assume that most people use private files with some sort of node access. When a user has access to a node, access to private files attached to the node should also be granted. When a private file is not attached to a node the user has access to, access to the file should be denied. This is not possible with returning -1 and granting the View private files permission.
The problem in #2164527: Cannot deny access to private files can be fixed in another way, either by implementing
hook_file_download()
in a custom module, by making sure that no other module returns headers (e.g. using node access), or by an additional setting in the File Entity module that allows for the unfriendly takeover of all files. The latter - in my opinion - should not be the default and users should be warned about the consequences.Comment #17
znerol CreditAttribution: znerol commentedIf the View private files permission cannot be implemented cleanly in file entity, then it should be removed completely. Flip-flopping the return value in every release is not only a nuisance for site owners but also may have security implications for some sites.
Comment #18
kyuubi CreditAttribution: kyuubi commentedHello,
First of all thank you for the patch it fixes the issue I was having with Webform Protected downloads.
Before the patch I had to implement my own solution by having to integrate the Webform Protected Downloads hook_file_download logic into my own module that can determine which module to delegate it to.
Also this required the use of the view private files (so that the hook is triggered).
I agree with dunix on in the sense that the way File Entity is returning currently just makes it impossible to play nice with any module that deals with granting access to private files to users (say anonymous), as we are seeing with the current thread (Organic Groups, FileDepot, Webform Protected Downloads).
Comment #19
Blackice2999 CreditAttribution: Blackice2999 commentedHi @all,
why not simple implement hook_file_entity_access() instead of hook_file_download from now? If you allow the access to the file entiy u got access to the private file also.
So the expected behavior is the same as the entity view.
But one thing is irritate me... why check for "view" in file_entity_file_download and not check for "download" ?
file_entity_file_download:
Here a example how i implemented it currently (very specific but could be help someone):
Comment #20
svn7svn CreditAttribution: svn7svn commentedI just ran some updates on my site two weeks ago and lost access to my purchased files. even as user 1. any idea if the patch above will resolve the current issue? I've had file downloads working fine since Sept until the recent updates.
Comment #21
rooby CreditAttribution: rooby commented+1 for #17
It would be good to get some stability in file permissions.
Comment #22
broeker CreditAttribution: broeker commentedIt appears this small patch was rolled into DEV at some point, but we are now getting Access Denied errors on all private files again even as User 1 and with all "View private files" permissions set correctly. It has been awhile but if I recall correctly:
a. We originally applied this patch and it fixed our issue
b. We updated module to most recent DEV (which appears to include said patch) but we are now back to access denied on all private file links
Not sure where things stand or if anybody else is seeing this but thought I'l post a report -- if/when we fix I will update.
Comment #23
kyuubi CreditAttribution: kyuubi commentedThis fixes it for me.
I also tried the latest DEV version which seems to have this committed and found no issues with accessing private files.
Comment #24
michaellenahan CreditAttribution: michaellenahan at erdfisch commented@Blackice2999 - thank you for posting your code at #19
I implemented this code but hit the following error when uploading files using the media module: "Upload a new file field is required."
The problem is described here: https://www.drupal.org/node/2308737
As a result, I needed to amend the code as follows.
Comment #25
deanflory CreditAttribution: deanflory as a volunteer commentedSo, when I attempt to apply this patch is states it already has been. Is this issue closed and the patch applied already?
I'm still having issues with preview images not showing up from my private file system but I don't know if this module is the culprit or if it's Drupal 7.41.
Comment #26
michaellenahan CreditAttribution: michaellenahan at erdfisch commented@deanflory - the patch at #1 was indeed committed to on 2014-10-29 (see #7)
http://cgit.drupalcode.org/file_entity/commit/?id=5b5e5a5
The rest of the discussion in this thread is about subsequent permissions issues that people encountered, even with the change at #1 in place.
"I'm still having issues with preview images not showing up from my private file system but I don't know if this module is the culprit or if it's Drupal 7.41"
It may be that you need do something to implement hook_file_entity_access() to get around this.
Comment #27
David_Rothstein CreditAttribution: David_Rothstein as a volunteer commentedI can see both arguments here personally... that said, the patch was committed to Drupal 7 a long time ago and it is probably a little late to revert it again. Right now, the Drupal 7 and Drupal 8 versions of the module actually have different behaviors, so maybe should discuss here what is the correct behavior going forward and whether this should be changed in Drupal 8 too or not.