Skip to content

Add Private Media feature: attachments private by default#458

Open
mikelittle wants to merge 7 commits intomasterfrom
issue-162-default-private-uploads-2
Open

Add Private Media feature: attachments private by default#458
mikelittle wants to merge 7 commits intomasterfrom
issue-162-default-private-uploads-2

Conversation

@mikelittle
Copy link
Contributor

Summary

  • Implements the Private Media feature which makes uploaded media attachments private by default on S3-hosted sites
  • Attachments only become publicly accessible when used in published content, marked as a site icon, flagged as legacy, or manually overridden
  • Includes media library UI (visibility column, row actions, bulk actions, modal sidebar), WP-CLI commands, and user documentation
  • Fresh implementation under Altis\Media\Private_Media namespace (not extending the existing issue-162-default-private-uploads branch)

Key components

  • Visibility logic — priority-based public/private determination (force-private > force-public > used-in-published > legacy > site-icon > default private)
  • Post lifecycle — hooks into transition_post_status and save_post to track publish/unpublish transitions and detect removed attachments
  • Content parser — regex extraction of attachment IDs/URLs from all Gutenberg block formats
  • Sanitisation — strips AWS signing parameters from content on save
  • Signed URLs — preview support for private images in draft/future posts
  • Query compatibilitypre_get_posts filter adds publish and private to attachment queries (always active, even when feature disabled)
  • Capability handlingmap_meta_cap filter grants read_post for private attachments to users with upload_files capability
  • Media library UI — visibility column, Make Public/Private row actions, bulk Set Visibility action, modal sidebar visibility dropdown
  • WP-CLImigrate, set-visibility, fix-attachments commands with --dry-run support
  • User documentationdocs/private-media.md with screenshots and configuration guide

Files

  • 13 PHP source files in inc/private_media/
  • 2 asset files (JS/CSS) in assets/
  • 3 integration point changes (load.php, inc/namespace.php, composer.json)
  • 9 integration test files (68 tests, 140 assertions)
  • 1 acceptance test file (4 browser-based UI tests)
  • User documentation with screenshots

Test plan

  • 68 integration tests passing (visibility, content parsing, post lifecycle, sanitisation, signed URLs, query compat, site icons, overrides)
  • 4 acceptance tests passing (upload defaults private, Make Public/Private row actions, Remove Override)
  • Manual verification: upload media, verify private status, publish post with image, verify attachment becomes public, unpublish, verify returns to private
  • Manual verification: test as Author role — media library browsing, featured image setting, content editing with private attachments
  • Add remaining screenshots to documentation (bulk confirmation, modal sidebar, post actions, success notice)

🤖 Generated with Claude Code

mikelittle and others added 4 commits March 11, 2026 16:30
Implement the Private Media feature which makes uploaded media attachments
private by default. Attachments only become publicly accessible when used
in published content, marked as a site icon, flagged as legacy, or manually
overridden via the UI/CLI.

Key components:
- Visibility logic with priority-based public/private determination
- Post lifecycle hooks to track publish/unpublish transitions
- Content parser to extract attachment references from block content
- AWS signing parameter sanitisation on save
- Signed URL support for draft/preview contexts
- Query compatibility layer (always active) for private post_status
- map_meta_cap filter so authors/editors can access private attachments
- Media library UI: row actions, bulk actions, modal visibility dropdown
- WP-CLI commands: migrate, set-visibility, fix-attachments
- 68 integration tests with S3 ACL mocking

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add a "Visibility" column to the media library list table showing
Private/Public status with forced override indicators. Add acceptance
tests for the media library UI: upload defaults to private, Make Public
and Make Private row actions, and Remove Override action.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add docs/private-media.md explaining the feature from a user perspective:
how uploads are private by default, how they become public when content
is published, how to manage visibility via quick actions, bulk actions
and the media editor sidebar, and configuration options for developers.

Includes screenshots of the media library visibility column and row
actions, with placeholders for additional screenshots to be added
manually (bulk confirmation, modal sidebar, post actions, success notice).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
mikelittle and others added 3 commits March 12, 2026 15:50
1. Add per-request static cache for attachment privacy checks to avoid
   repeated DB lookups when S3 Uploads calls the filter for every URL
   of every image size (~200 calls per media library page load).

2. Route signed image URLs through tachyon_url() in REST content.raw
   so X-Amz-* params get bundled into a presign query parameter.
   Without this, the browser hits CloudFront directly with S3 signing
   params which it cannot validate (host mismatch), resulting in 404.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant