Follow up for #1776796: Provide a better UX for creating, editing & managing draft revisions.
Problem/Motivation
When access workflow is in place, the fixed public / private sorage configuration is a problem:
- If site owner chooses public file storage, they suffer from PSA-2016-003
- If site owner chooses private file storage, they suffer from performance penalty. For example, on a campaign page with 50ish anonymous-user-submitted-and-reviewed testimonial photos, serving the page needs 51 Drupal bootstraps
Because of the performance cost of private files, a lot of websites use public files by default and sometimes involuntarily expose files.
Proposed resolution
These contrib modules implement a solution as a POC:
The basic idea is to check if a file can be accessed by anonymous users and move accordingly.
This could be implemented as a third option on file fields. (We probably should keep allowing to force public or private file storage.)
Comments
Comment #1
tstoecklerIn theory I agree that this would make lots of sense. The problem is that idea of "published"/"unpublished" is not common among all entity types but specific to nodes. File handling on nodes is managed by the file field, though, which is entity-type agnostic.
Now node.module *could* alter the file field form and hook into the field behavior, but...
Comment #2
agentrickardThis idea comes up a lot in our D7 projects, but I'm not sure how feasible it actually is. Some of the moving parts are:
Given the state of D8 feature freeze, I would suggest that the best we can do is allow this behavior to be defined in contrib, which means attacking only the garbage collection and possibly the WYSIWYG in this issue.
Comment #3
hass commentedWell this are some good questions.
I mainly think about the following critical issues:
If an attachment is already public in other content, it makes not sense to move around :-). I'm sure with some brainstorming we will find more examples why we need this. Adding a .htaccess files cannot really solve the issue as it does not work on IIS out of the box.
Comment #4
agentrickardRight, and I think a contrib workflow module can handle that if we solve problem 1 (bad garbage collection) and problem 2 (actually moving files from private:// to public://) and possibly problem 7 (WYSIWYG).
Comment #5
hass commented#2. Just a copy/move :-)
#7. Looks likely to be solved with UUIDs in D8 core if I remember correctly.
Comment #12
technikh commentedAny solution for this? I am looking for a solution in my D8 site.
Comment #13
szato commentedOur working D8 solution for the mentioned problem:
1) Move public files to private - to be able to manage file access.
2) Add entity_usage module with "Track file/image fields" patch to track images, files too. It works for WYSIWYG files too.
3) Implement your custom file access management based on entity_usage data with hooks: hook_file_access() (hook_ENTITY_TYPE_access) for referenced files and hook_file_download() for WYSIWYG files.
In 3) we are checking entity (node) view access to nodes from which is the file referenced. If at least one node view access is granted, we return AccessResult::allowed(), otherwise AccessResult::forbidden().
Comment #14
szato commentedIf you need tracking non-linked images added with CKEditor Image plugin, add "Add plugin for tracking (non linked) images inserted with WYSIWYG Image" patch.
Comment #20
claudiu.cristea@szato, your solution works but files in the private file system are expensive. Each file download requires PHP processing. A public file is just served by the webserver or frontend cache and that's a relief for Drupal/PHP
Comment #21
berdirYou can combine that with moving files between private and public, so you only need to do access checks as long as there is no public content using them. Not saying it's trivial to do that, at least not in a generic way, but it's... possible.
Comment #22
claudiu.cristea@Berdir, yes, I was thinking on a solution which combines both. I'm wondering whether such a feature could be made generic enough to create a contrib module.
Comment #23
berdirMaybe, if you check for access on any referenced entity for an anonymous user? And you probably also want to specifically handle media entities, so check the nodes/entities using the media, not just the media entity. Which means you need to depend on the entity_usage module as mentioned above (although possible a combination of both file usage and entity usage, to not require that patch).
Comment #24
claudiu.cristea@Berdir, it would be great if you have some time to review a first approach at https://www.drupal.org/project/unpublished_fileNot yet done: "check the nodes/entities using the media, not just the media entity" not implemented yet.EDIT: See #26
Comment #26
claudiu.cristeaOK, I have a complete solution but in an early stage of development, the File Visibility module.
Solution from #24 is abandoned.
Comment #28
geek-merlinComing from #3087660: Automatically move files to public / private storage, depending on referencing entities' access and #2904842: Make private file access handling respect the full entity reference chain, which lived for quite some time as a dup of this issue.
Maybe the title of this issue is not really perfect. Updating it accordingly (ymmv).
@claudiu, kudos for the file_visibility module!
It looks far more feature-rich and elaborated than my file_access_fix that i created some time ago and roughly corresponds to your unpublished_file POC.
So i am deprecating my module in favor of yours.
Comment #29
prudloff commentedCopying some info from #3087660: Automatically move files to public / private storage, depending on referencing entities' access.
Comment #30
dqdI think the new issue title is a little bit blurry now. From a UX point of view a "file" can not be set "(un)published" in Drupal core yet in the same sense like content, but an entity holding a file, like media or nodes with image fields, or nodes with body embedded images can.
There is another issue with unpublished (media) entities holding files not being 100% unpublished in references. Which is another issue in core, but out of the scope of this issue.
From my understanding this issue here is about the file accessibility in connection with unpublished entities referencing the file, where files (not media) keep being accessible even if unused or being part of unpublished content (references). The title should follow this a little bit clearer to distinguish between these both issues. The later isn't probably even not documented yet (I will take a look next days).
Another contrib project not mentioned yet in this scope: https://www.drupal.org/project/file_unpublish