Discord-only login: drop WebDAV/app-password path from docs and generated config comments
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@@ -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.
|
- **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
|
- **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.
|
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
|
- **Discord login only, no passwords anywhere** → no WebDAV (a mounted drive can't do a browser login).
|
||||||
can't do a browser login).
|
Editors download from copyparty's web UI (zip/tar for folders).
|
||||||
|
|
||||||
## Target layout
|
## Target layout
|
||||||
|
|
||||||
@@ -190,7 +190,7 @@ Checklist:
|
|||||||
replaces today's workaround of logging in as the local `admin` account to modify streams/clips)
|
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
|
- [ ] 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)
|
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
|
- [ ] policy on the Application: only `editors` + `admins` + `streamers` may pass
|
||||||
|
|
||||||
### Phase 6 — Syncthing UI + dump behind Authentik (built together with phase 5; apply pending)
|
### Phase 6 — Syncthing UI + dump behind Authentik (built together with phase 5; apply pending)
|
||||||
|
|||||||
@@ -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=`
|
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).
|
(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
|
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
|
`admins`/`media-admins` dump anyone's night. Leave "Intercept header authentication" **off**: login is
|
||||||
provider so WebDAV clients can log in with Authentik app passwords. `./configure.py` apply regenerates the Caddy blocks; a user outside the
|
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.
|
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`).
|
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
|
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
|
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.
|
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**
|
No WebDAV: login is Discord only (no passwords of any kind), and a mounted drive cannot do a browser login.
|
||||||
(auth.HOST → your user settings → Tokens and App passwords → create). The proxy provider must have
|
Download from the browser: single files, or select files/folders and use copyparty's zip/tar download.
|
||||||
"Intercept header authentication" enabled for this to work.
|
|
||||||
|
|
||||||
Every `.mp4` an editor sees is the same kind of file (see "Editing standard"). Raw clipper output that
|
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).
|
needed converting is kept in a hidden `.src/` folder next to it (media-admins can show dotfiles in copyparty).
|
||||||
|
|||||||
@@ -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 |
|
| 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 | — |
|
| 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 | 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 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 |
|
| 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 `<user>/HelmetCam-<date>`; no OBS needed | Live portal → Go Live | Discord; key fetched for the logged-in user — **verified end to end** (publish → `.live` → sweep → title folder) |
|
| Streamer (Windows) | **Go Live** from the browser: pick the WarDogs window (+audio on Windows Chrome 141+; Linux/Mac video only), streams as `<user>/HelmetCam-<date>`; 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.
|
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`).
|
2. **Register the runner** (`./registerGiteaRunner.sh`).
|
||||||
3. **`bot` CNAME + Authentik proxy provider** — first use of forward-auth; proves the pattern for copyparty.
|
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).
|
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).
|
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.
|
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.
|
||||||
|
|||||||
@@ -372,8 +372,7 @@ def write_copyparty():
|
|||||||
Path("copyparty.conf").write_text("""# copyparty — behind Caddy + Authentik forward-auth. (generated by configure.py)
|
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 |).
|
# 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).
|
# 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*
|
# No WebDAV: login is Discord only (browser session); download via the web UI (zip/tar for folders).
|
||||||
# (the proxy provider must have "Intercept header authentication" enabled).
|
|
||||||
# Docs: https://github.com/9001/copyparty#identity-providers
|
# Docs: https://github.com/9001/copyparty#identity-providers
|
||||||
|
|
||||||
[global]
|
[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" 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(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("== 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:")
|
print("== streamers:")
|
||||||
for u, p in streamers.items():
|
for u, p in streamers.items():
|
||||||
print(f"\n {u} password {p}")
|
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" 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})")
|
print(f" Dock URL : https://{domain or 'HOST'}/dock/ (settings: host={domain or 'HOST'}, user={u}, pass={p})")
|
||||||
if not streamers: print(" (none)")
|
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" 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")
|
print(f" curl -s -o /dev/null -w '%{{http_code}}\\n' https://{domain or 'HOST'}/dump (expect 401)\n")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user