From 15402eeb82d5aede54debf2717a3f44629ef2885 Mon Sep 17 00:00:00 2001 From: Brandyn / Techy Date: Sat, 31 Oct 2026 15:00:48 -0500 Subject: [PATCH] Discord-only login: drop WebDAV/app-password path from docs and generated config comments Co-Authored-By: Claude Fable 5.1 --- CommunityDiscordMedia.md | 6 +++--- README.md | 9 ++++----- STATUS.md | 3 +-- configure.py | 7 +++---- 4 files changed, 11 insertions(+), 14 deletions(-) diff --git a/CommunityDiscordMedia.md b/CommunityDiscordMedia.md index 0c5a827..32903ab 100644 --- a/CommunityDiscordMedia.md +++ b/CommunityDiscordMedia.md @@ -37,8 +37,8 @@ Bundle: `vanguard-stream/` in this repo; live copy at `~/vanguard-stream` on the - **Raw clipper files live in hidden `.src/` folders** so Jellyfin and copyparty show one item per clip. - **Hostnames:** `auth.` and `watch.` are CNAMEs to the main host. Caddy routes by SNI, Let's Encrypt follows CNAMEs. One A record to change if the IP ever moves. -- **WebDAV through Authentik** uses Authentik app passwords as HTTP basic auth (a mounted drive - can't do a browser login). +- **Discord login only, no passwords anywhere** → no WebDAV (a mounted drive can't do a browser login). + Editors download from copyparty's web UI (zip/tar for folders). ## Target layout @@ -190,7 +190,7 @@ Checklist: replaces today's workaround of logging in as the local `admin` account to modify streams/clips) - [ ] keep the local accounts in `copyparty.conf` until an `editors` Discord user has browsed and downloaded through the new path; then remove them (`configure.py` drops the editors section) -- [ ] WebDAV: editor creates an app password in Authentik → mounts with Discord username + app password +- [x] decided: no WebDAV (Discord login only); browser downloads - [ ] policy on the Application: only `editors` + `admins` + `streamers` may pass ### Phase 6 — Syncthing UI + dump behind Authentik (built together with phase 5; apply pending) diff --git a/README.md b/README.md index a7e08fa..586953c 100644 --- a/README.md +++ b/README.md @@ -228,8 +228,8 @@ Design: **Authentik authenticates once for the whole domain; Caddy authorizes pe 3. Per-host group requirement = `.env`: `BOT_REQUIRE_GROUP=bot-users` (default), `LIVE_REQUIRE_GROUP=` (empty = any logged-in member), `SYNC_REQUIRE_GROUP=media-admins` (the `/sync` Syncthing UI on the main host). On the main host copyparty itself authorizes by group (`editors`, `media-admins`); the dump endpoint lets - `admins`/`media-admins` dump anyone's night. Enable **"Intercept header authentication"** on the proxy - provider so WebDAV clients can log in with Authentik app passwords. `./configure.py` apply regenerates the Caddy blocks; a user outside the + `admins`/`media-admins` dump anyone's night. Leave "Intercept header authentication" **off**: login is + Discord only, no app passwords, no WebDAV. `./configure.py` apply regenerates the Caddy blocks; a user outside the group gets a 403 from Caddy before the app sees the request. 4. Discord roles → groups: Directory → Groups: create `bot-users` (and keep `streamers`, `editors`, `admins`). Discord source → Scopes: `guilds guilds.members.read`. Customization → Policies → Expression Policy @@ -248,9 +248,8 @@ Log in with Discord at https://media.example.com/ (copyparty behind Caddy + Auth group: **editors** read streams and clips and write `/finals`; **media-admins** have full rights everywhere including `/trash`. Scrub any `.mp4` in the browser, download what you want. -WebDAV mount: same URL. Username = your Authentik username, password = an **Authentik app password** -(auth.HOST → your user settings → Tokens and App passwords → create). The proxy provider must have -"Intercept header authentication" enabled for this to work. +No WebDAV: login is Discord only (no passwords of any kind), and a mounted drive cannot do a browser login. +Download from the browser: single files, or select files/folders and use copyparty's zip/tar download. Every `.mp4` an editor sees is the same kind of file (see "Editing standard"). Raw clipper output that needed converting is kept in a hidden `.src/` folder next to it (media-admins can show dotfiles in copyparty). diff --git a/STATUS.md b/STATUS.md index e2fff3f..28adad4 100644 --- a/STATUS.md +++ b/STATUS.md @@ -28,7 +28,6 @@ Source of truth: this repo, `techy/Media-Server-Setup` on the stack's own Gitea | Streamer | Type a title, Go Live, Stop. "Dump tonight" if it was junk (3-day undo) | OBS browser dock `https://ovh1…/dock/` | Discord login in the dock (once); stream password in dock settings for the OBS key | | Gamer | Nothing; clips save where they always did | their clipper + Syncthing, paired once | — | | Editor | Browse by streamer/title, scrub in browser, download originals, upload finals | copyparty `https://ovh1…/` | Discord (Authentik); rights by group `editors` / `media-admins` — **pending apply** | -| Editor | Mount the library as a drive | WebDAV, same URL | Authentik username + app password — **pending apply + "Intercept header authentication"** | | Anyone in the Discord server | Watch recordings and clips by streamer and season | Jellyfin `https://watch.…/` | Discord (Authentik) | | Anyone in the Discord server | Watch live: all active streams in dockable windows, audio follows focus, per-window mute/volume | Live portal `https://live.…/` | Discord (Authentik, domain-level) — live; viewer side not yet exercised during a stream | | Streamer (Windows) | **Go Live** from the browser: pick the WarDogs window (+audio on Windows Chrome 141+; Linux/Mac video only), streams as `/HelmetCam-`; no OBS needed | Live portal → Go Live | Discord; key fetched for the logged-in user — **verified end to end** (publish → `.live` → sweep → title folder) | @@ -69,7 +68,7 @@ Source of truth: this repo, `techy/Media-Server-Setup` on the stack's own Gitea 1d. Watch a real stream from a second browser: corner chip should say `webrtc`; confirm WarDogs audio came through. 2. **Register the runner** (`./registerGiteaRunner.sh`). 3. **`bot` CNAME + Authentik proxy provider** — first use of forward-auth; proves the pattern for copyparty. -4. **Apply phase 5+6** (copyparty, dock, dump, /sync behind Authentik; group permissions). Authentik side: group `media-admins` (techy in it), "Intercept header authentication" on the provider for WebDAV app passwords. +4. **Apply phase 5+6** (copyparty, dock, dump, /sync behind Authentik; group permissions). Authentik side: group `media-admins` with techy in it. Decision: Discord login only → no WebDAV; browser downloads (zip/tar) instead. 5. Dock fetches the caller's own stream key (phase 7) — or skip straight to phase 11 (no keys). 6. **Gitea login via Authentik** (OIDC source, auto-register, `admins` → Gitea admin). 7. **Housekeeping**: pin `AUTHENTIK_TAG` in `.env`, rotate the Discord client secret that was in a screenshot, nightly Postgres dump, Jellyfin login branding (Discord button first), check a non-admin Discord user's Jellyfin view. diff --git a/configure.py b/configure.py index 5a918c6..995b36f 100755 --- a/configure.py +++ b/configure.py @@ -372,8 +372,7 @@ def write_copyparty(): Path("copyparty.conf").write_text("""# copyparty — behind Caddy + Authentik forward-auth. (generated by configure.py) # Identity comes from the proxy: X-Authentik-Username / X-Authentik-Groups (groups separated by |). # No local accounts. Groups: editors (read streams/clips, write finals), media-admins (everything incl. trash). -# WebDAV: same URL, HTTP Basic with the Authentik username + an Authentik *app password* -# (the proxy provider must have "Intercept header authentication" enabled). +# No WebDAV: login is Discord only (browser session); download via the web UI (zip/tar for folders). # Docs: https://github.com/9001/copyparty#identity-providers [global] @@ -471,7 +470,7 @@ def show(domain, admin_pw, streamers, editors, auth_host="", watch_host="", git_ print(f" bot : db {env.get('BOT_DB_NAME','vanguardbot')} user {env.get('BOT_DB_USER','bot')} pass {env.get('BOT_DB_PASSWORD','(run apply)')}") print(f" gitea : db gitea user gitea pass {env.get('GITEA_DB_PASSWORD','(run apply)')} (created on MariaDB first init, else ./createGiteaDb.sh)") print("== access : by Authentik group — editors (read streams/clips, write finals), media-admins (everything), admins (dump anyone)") - print(" WebDAV: Authentik username + an Authentik app password") + print(" Discord login only — no WebDAV; downloads via the web UI") print("== streamers:") for u, p in streamers.items(): print(f"\n {u} password {p}") @@ -480,7 +479,7 @@ def show(domain, admin_pw, streamers, editors, auth_host="", watch_host="", git_ print(f" SRT : srt://{domain or 'HOST'}:8890?streamid=publish:{u}/TITLE:{u}:{p}") print(f" Dock URL : https://{domain or 'HOST'}/dock/ (settings: host={domain or 'HOST'}, user={u}, pass={p})") if not streamers: print(" (none)") - print(f"\n editors log in with Discord at https://{domain or 'HOST'}/ — WebDAV at the same URL (app password)") + print(f"\n editors log in with Discord at https://{domain or 'HOST'}/") print(f" verify: curl -sI https://{domain or 'HOST'}/dock/ | head -1 (expect 200)") print(f" curl -s -o /dev/null -w '%{{http_code}}\\n' https://{domain or 'HOST'}/dump (expect 401)\n")