Make WordPress Core

Opened 6 years ago

Last modified 6 weeks ago

#17255 new defect (bug)

More statuses (like draft and/or private) for media files

Reported by: jane Owned by:
Milestone: Future Release Priority: normal
Severity: normal Version: 3.1
Component: Media Keywords: needs-patch
Focuses: Cc:


It's weird that media files don't carry any concept of pub status. If someone wants to upload files (either attached to a post or directly into the library), they should be able to keep them hidden via 'draft' status just like any other content. The fact that people can link to things that haven't been explicitly published is bizarre.

Media files should have a pub status. If uploaded as post attachment, should inherit publish on post publish. Would then need a workflow for if a post becomes unpublished containing media, as it then lives in library for use by other content, so would need to ask if user wants to unpub media files as well. This would be a big shift, so would make most sense as part of a media redux with a long notice period for plugin and theme authors.

Change History (25)

#1 @scribu
6 years ago

This is the reason why media doesn't have a "Trash" option either.

#2 @greuben
6 years ago

  • Keywords 2nd-opinion added

Media files are stored on file system not in database. Having pub status like 'Draft', 'Trash' etc. doesn't make sense as they are still accessible via direct link.

#3 @nacin
6 years ago

Originally posted in #17254 -- (in turn, these aren't entirely new ideas; they came up during 2.9 development)

We could create a random hash, store the hash in postmeta, and use the hash in the filename. Then on publish we can remove the hash from the filename. Works for draft and trash.

It's certainly not foolproof, but it's an idea.

We could also put them into their own uploads directory (in addition to the hash), that way the entire directory can be locked down in htaccess too.

#4 @aaroncampbell
6 years ago

  • Cc aaroncampbell added

#5 @johnbillion
6 years ago

You could prevent a contributor from using draft media anywhere else by rewriting the URLs and requiring that users be logged in to view the file.

For example:

example.com/draft-media/my-uploaded-file.png is actually a rewritten URL that points to a handler script (eg example.com/wp-admin/draft-media-handler.php?file=my-uploaded-file.png) that checks if the user has the correct capabilities to view the file. It serves the file if they have, and serves a 403 if not.

This way the actual file URL is never exposed (draft media could be stored in a hashed directory as nacin suggests) and sharing the draft media URL has limited consequences (only logged in users can see it).

The same system could be used to give media items a private status.

#6 @aaroncampbell
6 years ago

That's a pretty common solution, but the overhead is pretty severe. Instead of loading an image from the file system when it's requested we load all of WordPress and use it to pass through the image. On a page with 20 images you're loading WordPress 21 times.

#7 @scribu
6 years ago

I like nacin's suggestion better: put only non-published files in a locked down (and hard to guess) directory and then move them to wp-content/uploads when published.

Although it would yield better performance, it would also be a little more complicated, since direct links to those files (in the post content, for example) would also have to be updated.

#8 @pento
6 years ago

  • Cc gary@… added

Would something like johnbillion's suggestion be possible, with a lightweight auth lib, instead of all of WordPress?

The primary thing that an admin would want to restrict by is user privileges, so it could just load and check them. To avoid many database hits, the first time could set a cookie with the user privileges (encrypt using AUTH_KEY or something similar, to make sure it can't be faked).

#9 @mindctrl
5 years ago

  • Cc mindctrl added

#10 @lkraav
4 years ago

  • Cc leho@… added

#11 @brasofilo
4 years ago

  • Cc brasofilo@… added

#12 @ericlewis
3 years ago

My mental model of media in WordPress is similar to uploading to a Dropbox public folder, or an FTP server, or my local filesystem. Either media exists or it doesn't.

I don't see much to gain here, while creating a need for overly decorated UI that most users wouldn't need. What are the good use cases for this?

#13 @rezon8dev
3 years ago

Use Case: content is posted for review and what is posted is really bad, so the client says if we post that image in this article, we will get sued. But because the way media is handled even though the post was published privately and never made public the media is still there and can be accessed and may have been cached if it was a pdf version of the actual post. I think the concept of value here is published privately and the use case is workflow. This is a fairly important item in my world of 50+ sites being managed. I like the idea of using the hash in the filename and a separate directory for this media to be staged in (before being published publically) and moved to in the case of unpublishing or making a content item private.

#14 @wonderboymusic
2 years ago

  • Summary changed from Draft status for media files to More statuses (like draft and/or private) for media files

#15 @wonderboymusic
2 years ago

  • Keywords needs-patch added; 2nd-opinion removed
  • Milestone changed from Awaiting Review to Future Release

#16 @wonderboymusic
2 years ago

#28796 was marked as a duplicate.

#17 @netweb
2 years ago

#33230 was marked as a duplicate.

#18 @SergeyBiryukov
17 months ago

#36370 was marked as a duplicate.

#19 @ticktockphoto
17 months ago

Just seeing this is a 5 yr old post after submitting my find. For those looking for a temporary solution, I'm using an htaccess rule, which honestly would be frustrating to do for hundreds or thousands of password protected posts, but does work.

Example in the case of my site and ticket https://core.trac.wordpress.org/ticket/36370 my solution is as follows:

redirectmatch 301 /aiden-joseph-leto-1-month-pictures/(.*)/$ /aiden-joseph-leto-1-month-pictures/

This allows the password protected page to be seen while child pages redirect to the parent page. Hopefully anyone else finding this issue can use it as a temporary fix until we have an official patch/feature added for this.


#20 @joemcgill
11 months ago

It seems that are several use cases to consider here.

The one that has been covered most clearly thus far (and the most obvious) is how to limit visibility to the actual media files on the fileserver. I agree with @aaroncampbell that we don't want to load WP each time a browser requests a media asset and I also agree with reservations about custom .htaccess solutions. Something like @johnbillion + @pento describes is probably the right way to go here if we want to limit visibility to the actual files, but I'm not convinced this is a requirement for most WordPress sites, so it may be ok to leave this as plugin material.

Another use case to consider, which I believe we can address, is how we expose post/meta data about an attachment whenever the attachment has a post status of 'private' or 'draft' (either directly, or by inheriting post status from its parent). We currently seem to be inconsistent about what information we make private and what is public. For example, attachments that are attached to private posts still show up in the media library for authors who are not able to read the post the attachment is attached to. We addressed some related UI issues in #37186, but that didn't address the root issue. I wonder if inheriting some capabilities from the post parent would be worth pursuing, as it could fix issues like #36370.

Similar concerns have also come up with the REST API project when deciding what data should be protected whenever an attachment attached to a private post is set as the featured image of a public post.

This ticket was mentioned in Slack in #core by joemcgill. View the logs.

11 months ago

This ticket was mentioned in Slack in #core-images by joemcgill. View the logs.

11 months ago

This ticket was mentioned in Slack in #core by clorith. View the logs.

6 weeks ago

#24 @dougal
6 weeks ago

This was discussed on Slack today. My two-cents:

A user who uploads an image (or whatever media) to a private post might have a reasonable expectation that the image itself would be private, too. If UserA makes PrivatePostA with AttachmentA, then UserB probably should not have access to that media from the Media Library.

If UserA (or another user with sufficient capabilities) then creates PublicPostA, and uses AttachmentA as its Featured Image, it then should become okay for that attachment to become public in some way. Either by flagging it public in the posts table, or by creating a duplicate of the media as a separate attachment, AttachmentA2, as a child of PublicPostA. Personally, I favor the idea of duplication, because I just feel like we should reenforce the idea that any child object of a private post should also be private.

As far as the media URL itself goes (as opposed to the attachment post/meta in the database), I think it's reasonable to leave that as-is (with no attempt to protect direct access, even if the related attachment is private). If extra protections are desired at the media URL level, that needs to be left to the server or in plugin territory.

#25 @joyously
6 weeks ago

Don't forget to take into account the possible order of actions.
UserA could create PostA with an attachment, and later make that post private. In the meantime, the attachment could be used elsewhere (non-private). It doesn't always happen in the order is commonly thought of as normal.

Note: See TracTickets for help on using tickets.