Media storage implementation #4

Merged
blacklight merged 19 commits from feat/media-storage into main 2026-08-20 23:35:21 +02:00
Owner
  • Dependencies, config, and interface
  • LocalStorage — aiofiles and url()
  • S3Storage — aioboto3, multipart, and url()
  • StoredFile model and relationships
  • StorageService and dependency injection
  • Garbage collection task and beat schedule
  • File upload, metadata, and download API endpoints
  • ACL management for media items access

Closes: #3

- [x] Dependencies, config, and interface - [x] LocalStorage — aiofiles and `url()` - [x] S3Storage — aioboto3, multipart, and `url()` - [x] `StoredFile` model and relationships - [x] `StorageService` and dependency injection - [x] Garbage collection task and beat schedule - [x] File upload, metadata, and download API endpoints - [x] ACL management for media items access Closes: #3
chore(gitignore): Ignore docs/features
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
4abac8b65c
blacklight force-pushed feat/media-storage from 4abac8b65c
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
to c35ba22e62
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-08-19 20:18:31 +02:00
Compare
refactor(storage): make LocalStorage async and block path traversal
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
552bdcb4fa
- Use aiofiles for non-blocking store/retrieve/delete/exists
- Add strict path resolver to prevent escaping base directory
- Add tests for large streaming writes and traversal rejection
feat(storage): enforce max upload size and stream S3 uploads
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
e0b9d31606
- Add max_upload_size to storage config and backends
- Enforce limits during local writes with cleanup on failure
- Switch S3 backend to async aioboto3 with multipart streaming and temp retrieval
- Expand config and storage tests for new behavior
feat: add StoredFile model and wire media file foreign keys
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
4cfa66c3d0
- Add StoredFile model and export from models package
- Link Album.cover_file, Track.audio_file, and Upload.stored_file via FKs
- Extend model tests to cover new fields and StoredFile persistence
feat(storage): add content-addressable StorageService and DI helper
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
8cb867f61c
- Add StorageService for hashing, dedup, URL, and delete operations
- Wire storage service dependency in API deps
- Add tests covering hashing, dedup, streaming, URLs, and delete
feat(tasks): add scheduled cleanup for orphaned stored files
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is failing
0601eb2d10
- add storage task to delete unreferenced StoredFile rows and backing files
- add Celery config for cleanup schedule and route storage tasks to queue
- register beat schedule for daily cleanup (default 03:00 UTC)
- add tests for cleanup behavior and schedule parsing
- Add /files routes with safe Content-Disposition handling
- Cache StorageService per app and refresh on storage config changes
- Add test coverage for auth, range requests, sanitization, and 404s
fix(storage): map upload size limit to 413 response
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is failing
a020091a2c
- Add FileSizeLimitExceededError and raise from storage size checks
- Catch size limit error in upload route and return HTTP 413
- Treat SVG with parameters as unsafe for inline serving
fix(storage): Addressed an off-by-one error in orphaned file cleanup count
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
a04e90df72
- Add Visibility enum and apply to media models
- Add ShareGrant and ShareToken models
- Add owner_id/visibility to stored files, tracks, and albums
- Update tests to cover defaults and new share models
feat: add ACL and sharing services for media visibility
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
c5de4b96a7
- Implement access rules (private/local/public), grants, and share tokens
- Support derived file access via tracks/albums with depth guard
- Add unit tests for ACL and sharing behavior
feat: propagate library owner to imported media and stored files
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
105138c5e9
- Set owner_id on imported tracks and newly created albums
- Apply owner_id/visibility when creating StoredFile rows; preserve on dedup
- Infer owner from Library in import task
- Add importer/storage tests for owner and visibility behavior
feat(api): add optional auth and ACL access dependency
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
620e451fb2
- Add get_current_user_optional and shared _get_current_user helper
- Add require_access() dependency with 404/403 behavior and share-token support
- Refactor ACL registry and add get_item() helper
- Add dependency tests for optional auth and access control
feat(api): add ACL-aware media endpoints with visibility + owner redaction
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
27132e54c6
- Implement list/get/create for albums, tracks, libraries, playlists, radios
- Add shared owner_id redaction helper and apply ACL filters to list queries
- Extend file upload with visibility/owner, duplicate header, and async hashing
- Add API tests covering visibility filtering, access control, and duplicates
feat(sharing): add share grants and revocable share URLs
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
52cb9dc418
- Add /shares, /share-urls CRUD and public /share/{token} resolver
- Centralize item-type validation and management authorization checks
- Support instance_domain share URL host and guard federation setup
- Extend sharing/acl helpers and add API tests for shares and tokens
fix(federation): gate Audio activities by visibility
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
398aa154c9
- Skip Create(Audio) and Audio serialization for non-public tracks
- Use public file download URL for audio stream links
- Add helpers for track/stream URL building and update tests
fix(acl): harden share tokens and adjust access tests
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
0bfb47917b
- Constant-time share token hash comparison
- Remove unused filter_accessible_ids helper + tests
- Add share-token access coverage for private item endpoints
- Test derived file download via public track visibility
fix(security): harden media storage, sharing and rate limiting
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
26a59aace1
- Enforce default max upload size and secure temporary file permissions
- Fix content-addressable dedup and orphan cleanup race conditions
- Redact internal storage paths and remove ownerless private access
- Move share tokens to headers/cookies and add rate limiting
- Distinguish S3 404 errors and restrict inline serving allowlist
blacklight changed title from WIP: Media storage implementation to Media storage implementation 2026-08-20 23:35:11 +02:00
blacklight deleted branch feat/media-storage 2026-08-20 23:35:21 +02:00
Sign in to join this conversation.
No description provided.