mirror of
https://github.com/xpltdco/media-rip.git
synced 2026-04-02 18:43:59 -06:00
Accept plaintext admin password — hash on startup, clear from memory
- New MEDIARIP__ADMIN__PASSWORD env var accepts plaintext password - Hashed via bcrypt on startup, plaintext cleared from memory immediately - PASSWORD_HASH still works for backward compatibility (takes precedence) - Removes the 'docker run python bcrypt' ceremony from setup flow - Updated README, docker-compose, .env.example to use plaintext
This commit is contained in:
parent
bfc7eba03f
commit
2bb97a0b30
6 changed files with 30 additions and 22 deletions
|
|
@ -7,13 +7,8 @@
|
|||
DOMAIN=media.example.com
|
||||
|
||||
# ── Admin credentials ──
|
||||
# Username for the admin panel
|
||||
ADMIN_USERNAME=admin
|
||||
|
||||
# Bcrypt password hash — generate with:
|
||||
# docker run --rm python:3.12-slim python -c \
|
||||
# "import bcrypt; print(bcrypt.hashpw(b'YOUR_PASSWORD', bcrypt.gensalt()).decode())"
|
||||
ADMIN_PASSWORD_HASH=
|
||||
ADMIN_PASSWORD=changeme
|
||||
|
||||
# ── Session mode (optional) ──
|
||||
# isolated = each browser has its own queue (default)
|
||||
|
|
|
|||
23
README.md
23
README.md
|
|
@ -53,7 +53,7 @@ These are the knobs most operators actually touch — all shown commented out in
|
|||
| `MEDIARIP__SESSION__MODE` | `isolated` | Set to `shared` for family/team use, `open` to disable sessions entirely |
|
||||
| `MEDIARIP__DOWNLOADS__MAX_CONCURRENT` | `3` | Increase for faster connections, decrease on low-spec hardware |
|
||||
| `MEDIARIP__PURGE__MAX_AGE_MINUTES` | `1440` | Raise for longer retention, or set `PURGE__ENABLED=false` to keep forever |
|
||||
| `MEDIARIP__ADMIN__PASSWORD_HASH` | _(empty)_ | Pre-set to skip the first-run wizard (useful for automated deployments) |
|
||||
| `MEDIARIP__ADMIN__PASSWORD` | _(empty)_ | Pre-set to skip the first-run wizard (useful for automated deployments) |
|
||||
|
||||
### All Settings
|
||||
|
||||
|
|
@ -76,7 +76,8 @@ These are the knobs most operators actually touch — all shown commented out in
|
|||
|----------|---------|-------------|
|
||||
| `MEDIARIP__ADMIN__ENABLED` | `true` | Enable admin panel |
|
||||
| `MEDIARIP__ADMIN__USERNAME` | `admin` | Admin username |
|
||||
| `MEDIARIP__ADMIN__PASSWORD_HASH` | _(empty)_ | Bcrypt hash of admin password |
|
||||
| `MEDIARIP__ADMIN__PASSWORD` | _(empty)_ | Admin password (plaintext — hashed on startup, never stored) |
|
||||
| `MEDIARIP__ADMIN__PASSWORD_HASH` | _(empty)_ | Bcrypt hash (alternative to plaintext — for advanced users) |
|
||||
|
||||
#### Purge
|
||||
|
||||
|
|
@ -115,17 +116,21 @@ These are the knobs most operators actually touch — all shown commented out in
|
|||
|
||||
Enabled by default. On first run, you'll be prompted to set a password in the browser.
|
||||
|
||||
To pre-configure for automated deployments (skip the wizard):
|
||||
To pre-configure for automated deployments (skip the wizard), set the password via environment variable or `.env` file:
|
||||
|
||||
```yaml
|
||||
# docker-compose.yml
|
||||
environment:
|
||||
- MEDIARIP__ADMIN__PASSWORD=your-password-here
|
||||
```
|
||||
|
||||
```bash
|
||||
# Generate a bcrypt hash
|
||||
docker run --rm python:3.12-slim python -c \
|
||||
"import bcrypt; print(bcrypt.hashpw(b'YOUR_PASSWORD', bcrypt.gensalt()).decode())"
|
||||
|
||||
# Then set in docker-compose.yml:
|
||||
# MEDIARIP__ADMIN__PASSWORD_HASH=$2b$12$...your.hash...
|
||||
# Or in .env file
|
||||
MEDIARIP__ADMIN__PASSWORD=your-password-here
|
||||
```
|
||||
|
||||
The plaintext password is hashed on startup and cleared from memory — it's never stored or logged.
|
||||
|
||||
### Troubleshooting: YouTube 403 Errors
|
||||
|
||||
YouTube downloads work out of the box — yt-dlp automatically selects the right player clients. If you do hit HTTP 403 errors, it's usually one of:
|
||||
|
|
|
|||
|
|
@ -97,7 +97,8 @@ class AdminConfig(BaseModel):
|
|||
|
||||
enabled: bool = True
|
||||
username: str = "admin"
|
||||
password_hash: str = ""
|
||||
password: str = "" # Plaintext — hashed on startup, never stored
|
||||
password_hash: str = "" # Bcrypt hash — set directly or derived from password
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -49,6 +49,17 @@ async def lifespan(app: FastAPI):
|
|||
config = AppConfig()
|
||||
logger.info("Config loaded from defaults + env vars (no YAML file)")
|
||||
|
||||
# --- Derive password hash from plaintext if provided ---
|
||||
if config.admin.password and not config.admin.password_hash:
|
||||
import bcrypt
|
||||
config.admin.password_hash = bcrypt.hashpw(
|
||||
config.admin.password.encode("utf-8"),
|
||||
bcrypt.gensalt(),
|
||||
).decode("utf-8")
|
||||
logger.info("Admin password hashed from plaintext config")
|
||||
# Clear plaintext from memory — only the hash is needed at runtime
|
||||
config.admin.password = ""
|
||||
|
||||
# --- TLS warning ---
|
||||
if config.admin.enabled and config.admin.password_hash:
|
||||
logger.warning(
|
||||
|
|
|
|||
|
|
@ -5,10 +5,6 @@
|
|||
# Setup:
|
||||
# 1. Copy .env.example to .env and fill in your values
|
||||
# 2. Run: docker compose -f docker-compose.example.yml up -d
|
||||
#
|
||||
# Generate a bcrypt password hash:
|
||||
# docker run --rm python:3.12-slim python -c \
|
||||
# "import bcrypt; print(bcrypt.hashpw(b'YOUR_PASSWORD', bcrypt.gensalt()).decode())"
|
||||
|
||||
services:
|
||||
media-rip:
|
||||
|
|
@ -25,7 +21,7 @@ services:
|
|||
# Admin panel
|
||||
MEDIARIP__ADMIN__ENABLED: "true"
|
||||
MEDIARIP__ADMIN__USERNAME: "${ADMIN_USERNAME:-admin}"
|
||||
MEDIARIP__ADMIN__PASSWORD_HASH: "${ADMIN_PASSWORD_HASH}"
|
||||
MEDIARIP__ADMIN__PASSWORD: "${ADMIN_PASSWORD}"
|
||||
# Session mode: isolated (default), shared, or open
|
||||
MEDIARIP__SESSION__MODE: "${SESSION_MODE:-isolated}"
|
||||
expose:
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ services:
|
|||
# - MEDIARIP__PURGE__MAX_AGE_MINUTES=1440
|
||||
#
|
||||
## Pre-set admin password (skip first-run wizard):
|
||||
# - MEDIARIP__ADMIN__PASSWORD_HASH=$2b$12$...
|
||||
# - MEDIARIP__ADMIN__PASSWORD=changeme
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8000/api/health"]
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue