mirror of
https://github.com/migatu/conjurer.git
synced 2026-07-21 17:22:09 +00:00
share: dockerize the file-share pipeline and document it
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>
This commit is contained in:
@@ -7,9 +7,13 @@ import argparse
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
# — CONFIGURATION — adjust as needed —
|
||||
APACHE_LOG = '/var/log/apache2/share_access.log' # <- point to your share-specific log!
|
||||
SHARE_DIR = Path('/var/www/html/share')
|
||||
# — CONFIGURATION — env-overridable; defaults = original bare-metal Pi layout —
|
||||
# APACHE_LOG must be the share-specific access log (see docker/share-vhost.conf);
|
||||
# pointing it at the site-wide log also works but wastes time scanning noise.
|
||||
APACHE_LOG = os.getenv('CONJURER_APACHE_LOG', '/var/log/apache2/share_access.log')
|
||||
SHARE_DIR = Path(os.getenv('CONJURER_SHARE_DIR', '/var/www/html/share'))
|
||||
# Seconds to keep a link alive after its FIRST download (not after creation).
|
||||
TTL_SECONDS = int(os.getenv('CONJURER_SHARE_TTL_SECONDS', '3600'))
|
||||
METADATA_FILE = SHARE_DIR / '.downloads.json'
|
||||
STATE_FILE = SHARE_DIR / '.logpos'
|
||||
# Regex to match lines like: "GET /share/abcdef1234... HTTP/1.1"
|
||||
@@ -66,7 +70,7 @@ def record_downloads(lines, metadata, args):
|
||||
|
||||
def revoke_old(metadata, args):
|
||||
now = time.time()
|
||||
to_remove = [tok for tok, ts in metadata.items() if now - ts >= 3600]
|
||||
to_remove = [tok for tok, ts in metadata.items() if now - ts >= TTL_SECONDS]
|
||||
for tok in to_remove:
|
||||
link = SHARE_DIR / tok
|
||||
try:
|
||||
@@ -78,7 +82,12 @@ def revoke_old(metadata, args):
|
||||
return bool(to_remove)
|
||||
|
||||
def main():
|
||||
p = argparse.ArgumentParser(description="Revoke share links 2min after download")
|
||||
p = argparse.ArgumentParser(
|
||||
description=(
|
||||
"Revoke share links CONJURER_SHARE_TTL_SECONDS "
|
||||
f"(currently {TTL_SECONDS}s) after their first download"
|
||||
)
|
||||
)
|
||||
p.add_argument('--debug', action='store_true', help='print debug info to stderr')
|
||||
args = p.parse_args()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user