mirror of
https://github.com/migatu/conjurer.git
synced 2026-07-21 09:12:09 +00:00
33ec1c0e35
The Python half of the short-lived share links lived in the repo; the Apache config and the cron entries that make it work were hand-placed on the host, so the feature could not be rebuilt from a checkout. This adds the missing half. Scripts (defaults unchanged, so existing bare-metal cron keeps working): * scan_shares.py / revoke_shares.py take their paths from CONJURER_SHARE_* instead of hardcoding the Pi layout, and create their parent dirs; * the revoke TTL is now CONJURER_SHARE_TTL_SECONDS. Its --help claimed "2min" while the code used a hardcoded 3600 - the help text now reports the real, configured value. New share service: * docker/Dockerfile.share - Apache + the two jobs, reusing the same scripts rather than forking copies; * docker/share-vhost.conf.tpl - the previously undocumented Apache half. Three settings are load-bearing and commented as such: +FollowSymLinks (the shares ARE symlinks), -Indexes (a listing would expose every live token), and a deny rule for dotfiles (revoke_shares.py keeps .downloads.json - a map of every live token - inside the served directory); * docker/entrypoint.share.sh - renders the vhost, seeds the index on first run, then runs scanner/revoker in sleep loops beside Apache (no cron, so their output shows up in docker logs); * compose + env example, incl. the two volumes that MUST be shared with the musician (it creates the links and reads the index). docs/deployment/FILE_SHARING.md documents the mechanism, both deployment routes (docker and existing host Apache), the Discord command, why each Apache setting matters, verification commands, and the known limitations - notably that a link nobody ever downloads is never revoked, since the TTL starts at first download. Verified: scanner and revoker exercised end-to-end against temp dirs (index built; token recorded from a combined-format log line and the symlink unlinked). Compose file not validated - no docker on this machine. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
50 lines
2.1 KiB
Smarty
50 lines
2.1 KiB
Smarty
# Apache vhost for the Conjurer file-share links.
|
|
#
|
|
# The entrypoint substitutes __SERVER_NAME__ from CONJURER_SHARE_SERVER_NAME and
|
|
# writes the result to /etc/apache2/sites-available/000-default.conf (same
|
|
# pattern as docker/icecast.xml.tpl).
|
|
#
|
|
# What this serves: media_search_functions.publish() creates a symlink named
|
|
# after a random 32-hex token inside the share dir, pointing at a file in the
|
|
# media library. Apache hands that file out at /share/<token>; revoke_shares.py
|
|
# later unlinks it. Nothing is ever copied.
|
|
|
|
<VirtualHost *:80>
|
|
ServerName __SERVER_NAME__
|
|
DocumentRoot /var/www/html
|
|
|
|
# The share links ARE symlinks into the media library, so FollowSymLinks is
|
|
# mandatory. SymLinksIfOwnerMatch is deliberately NOT used: the targets are
|
|
# owned by whoever owns the media, not by www-data, so it would break every
|
|
# link. -Indexes is equally mandatory - a directory listing here would hand
|
|
# out every currently live token at once.
|
|
<Directory /var/www/html/share>
|
|
Options +FollowSymLinks -Indexes
|
|
AllowOverride None
|
|
Require all granted
|
|
|
|
# revoke_shares.py keeps its state (.downloads.json, .logpos) in this
|
|
# very directory. .downloads.json maps every live token to its download
|
|
# time, so serving it would leak the entire active link set.
|
|
<FilesMatch "^\.">
|
|
Require all denied
|
|
</FilesMatch>
|
|
</Directory>
|
|
|
|
# Nothing outside /share is published. The more specific block above wins
|
|
# for the share dir itself.
|
|
<Directory /var/www/html>
|
|
Options -Indexes -FollowSymLinks
|
|
AllowOverride None
|
|
Require all denied
|
|
</Directory>
|
|
|
|
# Dedicated access log. revoke_shares.py tails exactly this file and matches
|
|
# the standard "%r" request line against:
|
|
# "\s*GET\s+/share/([0-9a-f]{32})\s+HTTP/
|
|
# so the format must stay `combined` (or any format containing %r).
|
|
SetEnvIf Request_URI "^/share/" conjurer_share
|
|
CustomLog ${APACHE_LOG_DIR}/share_access.log combined env=conjurer_share
|
|
ErrorLog ${APACHE_LOG_DIR}/share_error.log
|
|
</VirtualHost>
|