kaledonya clips: a Discord-friendly clip site on top of Zipline

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
esefandClaude Opus 5.5 committed 2026-10-07 20:46:48 +03:00
commit e6f8905377
34 files changed
+2917

No files matched your search

+382
View File
@@ -0,0 +1,382 @@
import json
import math
import re
from urllib.parse import quote, unquote
import httpx
import pytest
from fastapi.testclient import TestClient
from app.server import Settings, create_app
def mkfile(fid, name, size=100, thumb=True):
return {
"id": fid, "name": name, "originalName": name, "size": size, "type": "video/mp4", "views": 3,
"createdAt": "2026-10-01T16:46:15.378Z", "deletesAt": "2026-12-30T16:46:15.375Z",
"thumbnail": {"path": f".thumbnail.{fid}.jpg"} if thumb else None, "tags": [], "url": "/" + name,
}
class FakeZipline:
def __init__(self):
self.users = {"alice": ("pw", "tok-alice"), "bob": ("pw2", "tok-bob")}
self.files = {
"tok-alice": [mkfile("e1", "clutch.mp4"), mkfile("e2", "çılgın-#1.mp4", thumb=False)],
"tok-bob": [mkfile("c1", "friend.mp4")],
}
self.down = False
self.calls = []
def owner(self, tok):
return next((name for name, (_, t) in self.users.items() if t == tok), None)
def handler(self, request: httpx.Request) -> httpx.Response:
if self.down:
raise httpx.ConnectError("down")
path, method = request.url.path, request.method
self.calls.append((method, path, request.headers.get("authorization"), request.headers.get("cookie")))
if path == "/api/auth/login":
body = json.loads(request.content)
user = self.users.get(body["username"])
if not user or user[0] != body["password"]:
return httpx.Response(400, json={"error": "E1044: Invalid username or password"})
return httpx.Response(
200, json={"user": {"id": "u-" + body["username"], "username": body["username"]}},
headers={"set-cookie": f"zipline_session=sess-{body['username']}; Max-Age=1209600; Path=/; HttpOnly; Secure; SameSite=Lax"},
)
if path == "/api/user/token":
cookie = request.headers.get("cookie") or ""
for name, (_, tok) in self.users.items():
if f"zipline_session=sess-{name}" in cookie:
return httpx.Response(200, json={"token": tok})
return httpx.Response(401, json={"error": "E2001: Invalid token"})
if method == "HEAD":
name = unquote(path[1:])
f = next((f for files in self.files.values() for f in files if f["name"] == name), None)
if f is None:
return httpx.Response(404)
return httpx.Response(200, headers={"content-type": f["type"], "content-length": str(f["size"])})
tok = request.headers.get("authorization")
who = self.owner(tok)
if who is None:
return httpx.Response(401, json={"error": "E2001: Invalid token"})
mine = self.files.setdefault(tok, [])
if path == "/api/user":
return httpx.Response(200, json={"user": {"id": "u-" + who, "username": who, "role": "USER"}})
if path == "/api/user/stats":
return httpx.Response(200, json={"storageUsed": sum(f["size"] for f in mine)})
if path == "/api/user/files":
page = int(request.url.params.get("page", "1"))
per = int(request.url.params.get("perpage", "15"))
chunk = mine[(page - 1) * per: page * per]
return httpx.Response(200, json={"page": chunk, "total": len(mine), "pages": max(1, math.ceil(len(mine) / per))})
if path.startswith("/api/user/files/"):
ident = unquote(path[len("/api/user/files/"):])
f = next((f for f in mine if ident in (f["id"], f["name"])), None)
if f is None:
return httpx.Response(404, json={"error": "E4000: File not found"})
if method == "GET":
return httpx.Response(200, json=f)
if method == "PATCH":
f["name"] = json.loads(request.content)["name"]
return httpx.Response(200, json=f)
if method == "DELETE":
mine.remove(f)
return httpx.Response(200, json=f)
return httpx.Response(404, json={"error": "not found"})
@pytest.fixture
def zl():
return FakeZipline()
@pytest.fixture
def client(zl, tmp_path):
settings = Settings(zipline_url="http://zipline:3000", site_origin="https://clips.example.com",
upload_url="https://upload.example.com", max_bytes=1000, deletes_at="90d", work_dir=tmp_path)
return TestClient(create_app(settings, transport=httpx.MockTransport(zl.handler)), base_url="https://testserver")
def login(client, user="alice", pw="pw", ip="1.2.3.4"):
return client.post("/_site/api/login", json={"username": user, "password": pw}, headers={"cf-connecting-ip": ip})
def test_pages_serve_the_site(client):
for path in ("/", "/v/clutch.mp4", "/v/%C3%A7%C4%B1lg%C4%B1n-%231.mp4"):
r = client.get(path)
assert r.status_code == 200
assert "text/html" in r.headers["content-type"]
assert "/_site/static/app.js" in r.text
assert client.get("/_site/static/style.css").status_code == 200
@pytest.fixture
def fake_media(monkeypatch):
seen = []
monkeypatch.setattr("app.site_api.video_size", lambda url, length: seen.append(url) or (1920, 1080))
monkeypatch.setattr("app.site_api.still_jpeg", lambda url, length: seen.append(url) or b"jpeg-bytes")
return seen
def test_watch_page_has_discord_player_tags(client, fake_media):
# Discord gives up on big raw links; the /v/ page hands it the player URL, size and a still instead
r = client.get("/v/%C3%A7%C4%B1lg%C4%B1n-%231.mp4")
clip = "https://clips.example.com/%C3%A7%C4%B1lg%C4%B1n-%231.mp4"
assert f'<meta property="og:video" content="{clip}">' in r.text
assert '<meta property="og:video:type" content="video/mp4">' in r.text
assert '<meta property="og:video:width" content="1920">' in r.text
assert '<meta property="og:video:height" content="1080">' in r.text
assert ('<meta property="og:image" content="https://clips.example.com/_site/thumb/'
'%C3%A7%C4%B1lg%C4%B1n-%231.mp4">') in r.text
assert fake_media == ["http://zipline:3000/%C3%A7%C4%B1lg%C4%B1n-%231.mp4"]
def test_shared_clip_gets_a_random_stripe_color(client, fake_media):
colors = {re.search(r'name="theme-color" content="(#[0-9a-f]{6})"', client.get("/v/clutch.mp4").text).group(1)
for _ in range(5)}
assert len(colors) > 1 and "#3e4637" not in colors
assert 'name="theme-color" content="#3e4637"' in client.get("/").text
def test_watch_page_without_clip_has_no_player_tags(client, fake_media):
for path in ("/v/nope.mp4", '/v/"><script>alert(1)</script>'):
r = client.get(path)
assert r.status_code == 200
assert "og:video" not in r.text and "<script>alert" not in r.text
assert fake_media == []
def test_title_is_escaped(zl, client, fake_media):
zl.files["tok-alice"].append(mkfile("e3", 'a"><b>.mp4'))
r = client.get("/v/" + quote('a"><b>.mp4'))
assert '<meta property="og:title" content="a&quot;&gt;&lt;b&gt;.mp4">' in r.text
assert '"><b>' not in r.text
def test_thumbnail(client, fake_media):
r = client.get("/_site/thumb/clutch.mp4")
assert r.status_code == 200 and r.headers["content-type"] == "image/jpeg"
assert r.content == b"jpeg-bytes"
assert client.get("/_site/thumb/nope.mp4").status_code == 404
def test_public_file_needs_no_login(client):
r = client.get("/_site/api/public/clutch.mp4")
assert r.status_code == 200
assert r.json() == {"name": "clutch.mp4", "type": "video/mp4", "size": 100, "url": "/clutch.mp4",
"thumbnail": "/_site/thumb/clutch.mp4"}
assert r.headers["cache-control"] == "no-store, private"
assert client.get("/_site/api/public/nope.mp4").status_code == 404
def test_public_file_when_zipline_is_down(zl, client):
zl.down = True
assert client.get("/_site/api/public/clutch.mp4").status_code == 502
def test_config(client):
assert client.get("/_site/api/config").json() == {
"uploadUrl": "https://upload.example.com", "publicUrl": "https://clips.example.com",
"uploadHint": "Can't reach the upload server."}
def test_site_and_server_names_reach_the_page(zl, tmp_path, fake_media):
settings = Settings(zipline_url="http://zipline:3000", site_origin="https://clips.example.com",
site_name='my <clips>', server_name='box"1', work_dir=tmp_path)
client = TestClient(create_app(settings, transport=httpx.MockTransport(zl.handler)), base_url="https://testserver")
page = client.get("/").text
assert "<title>my &lt;clips&gt;</title>" in page
assert 'data-server="box&quot;1"' in page
assert '<meta property="og:site_name" content="my &lt;clips&gt;">' in client.get("/v/clutch.mp4").text
def test_login_sets_cookie(client):
r = login(client)
assert r.status_code == 200
assert r.json() == {"username": "alice"}
sc = r.headers["set-cookie"]
assert "ys=tok-alice" in sc
for flag in ("HttpOnly", "Secure", "SameSite=lax", "Max-Age=2592000", "Path=/"):
assert flag in sc
def test_login_wrong_password(client):
r = login(client, pw="nope")
assert r.status_code == 401
assert r.json() == {"error": "Wrong username or password."}
assert "ys=" not in r.headers.get("set-cookie", "")
def test_login_rate_limit_per_ip(client):
for _ in range(5):
assert login(client, pw="nope").status_code == 401
r = login(client)
assert r.status_code == 429
assert r.json() == {"error": "Too many tries, wait a few minutes."}
assert login(client, ip="9.9.9.9").status_code == 200
def test_login_zipline_down(client, zl):
zl.down = True
assert login(client).status_code == 502
def test_two_logins_get_own_tokens(client):
login(client, "alice", "pw")
r = login(client, "bob", "pw2")
assert "ys=tok-bob" in r.headers["set-cookie"]
assert client.get("/_site/api/me").json()["username"] == "bob"
def test_me_requires_login(client):
assert client.get("/_site/api/me").status_code == 401
def test_me(client):
login(client)
assert client.get("/_site/api/me").json() == {"username": "alice", "storageUsed": 200}
def test_revoked_token_clears_cookie(client):
client.cookies.set("ys", "revoked", domain="testserver")
r = client.get("/_site/api/files")
assert r.status_code == 401
assert 'ys=""' in r.headers["set-cookie"] or "ys=;" in r.headers["set-cookie"]
assert "Max-Age=0" in r.headers["set-cookie"]
def test_logout(client):
login(client)
r = client.post("/_site/api/logout")
assert r.json() == {"ok": True}
assert "Max-Age=0" in r.headers["set-cookie"]
assert client.get("/_site/api/me").status_code == 401
def test_files_list(client, zl):
login(client)
d = client.get("/_site/api/files").json()
assert d["total"] == 2 and d["pages"] == 1
first = d["files"][0]
assert first == {
"id": "e1", "name": "clutch.mp4", "size": 100, "type": "video/mp4", "views": 3,
"createdAt": "2026-10-01T16:46:15.378Z", "deletesAt": "2026-12-30T16:46:15.375Z",
"url": "/clutch.mp4", "thumbnail": "/raw/.thumbnail.e1.jpg",
}
assert d["files"][1]["url"] == "/" + quote("çılgın-#1.mp4")
assert d["files"][1]["thumbnail"] is None
sent = [c for c in zl.calls if c[1] == "/api/user/files"][0]
assert sent[2] == "tok-alice"
def test_files_paging(client, zl):
zl.files["tok-alice"] = [mkfile(f"f{i}", f"c{i}.mp4") for i in range(30)]
login(client)
p1 = client.get("/_site/api/files?page=1").json()
p2 = client.get("/_site/api/files?page=2").json()
assert len(p1["files"]) == 24 and p1["pages"] == 2
assert len(p2["files"]) == 6
def test_friend_cannot_see_alice_file(client):
login(client, "bob", "pw2")
r = client.get("/_site/api/files/e1")
assert r.status_code == 404
assert r.json() == {"error": "This clip doesn't exist (or isn't yours)."}
def test_file_by_unicode_name(client):
login(client)
r = client.get("/_site/api/files/" + quote("çılgın-#1.mp4"))
assert r.status_code == 200
assert r.json()["id"] == "e2"
def test_rename(client, zl):
login(client)
r = client.patch("/_site/api/files/e1", json={"name": "best clip ever.mp4"})
assert r.json() == {"name": "best-clip-ever.mp4"}
assert zl.files["tok-alice"][0]["name"] == "best-clip-ever.mp4"
def test_rename_strips_path(client, zl):
login(client)
assert client.patch("/_site/api/files/e1", json={"name": "../x y.mp4"}).json() == {"name": "x-y.mp4"}
def test_rename_taken(client, zl):
login(client)
r = client.patch("/_site/api/files/e1", json={"name": "friend.mp4"})
assert r.status_code == 409
assert r.json() == {"error": "That name is already used."}
assert not [c for c in zl.calls if c[0] == "PATCH"]
def test_delete(client, zl):
login(client)
assert client.delete("/_site/api/files/e1").json() == {"ok": True}
assert [f["id"] for f in zl.files["tok-alice"]] == ["e2"]
def test_files_zipline_down(client, zl):
login(client)
zl.down = True
r = client.get("/_site/api/files")
assert r.status_code == 502
assert r.json() == {"error": "Zipline isn't reachable right now."}
def test_upload_ticket(client):
assert client.post("/_site/api/upload-ticket").status_code == 401
login(client)
d = client.post("/_site/api/upload-ticket").json()
assert d["uploadUrl"] == "https://upload.example.com"
assert client.app.state.tickets.redeem(d["ticket"]) == "tok-alice"
def test_assets_are_versioned_and_page_not_cached(client):
# Cloudflare keeps .js/.css in browsers for 4 hours; a content hash in the URL makes updates show up at once
r = client.get("/")
assert r.headers["cache-control"] == "no-store"
assert client.get("/v/clip.mp4").headers["cache-control"] == "no-store"
assert "/_site/static/app.js?v=" in r.text
assert "/_site/static/style.css?v=" in r.text
assert "{{v}}" not in r.text
def test_api_answers_are_never_cached(client):
# Cloudflare caches anything ending in .mp4 by extension; a cached clip lookup would leak between users
for r in (client.get("/_site/api/files/clutch.mp4"), login(client), client.get("/_site/api/files/clutch.mp4"),
client.get("/_site/api/files/nope.mp4"), client.get("/_site/api/me"), client.get("/_site/api/config")):
assert r.headers.get("cache-control") == "no-store, private"
def test_login_limit_uses_forwarded_for_without_cloudflare(client):
# over the Tailscale address there's no CF-Connecting-IP; tailscale serve passes the tailnet IP in X-Forwarded-For
def tailnet_login(ip, pw):
return client.post("/_site/api/login", json={"username": "alice", "password": pw},
headers={"x-forwarded-for": ip})
for _ in range(5):
tailnet_login("100.64.0.5", "nope")
assert tailnet_login("100.64.0.5", "pw").status_code == 429
assert tailnet_login("100.64.0.9", "pw").status_code == 200
def test_other_account_login_doesnt_reset_the_limit(client):
# bob guessing alice's password can't clear their strikes by logging in as themselves
for _ in range(4):
login(client, "alice", "nope")
assert login(client, "bob", "pw2").status_code == 200
login(client, "alice", "nope")
assert login(client, "alice", "pw").status_code == 429
def test_empty_or_nested_file_id_is_404(client, zl):
login(client)
before = len(zl.calls)
for r in (client.get("/_site/api/files/"), client.delete("/_site/api/files/a%2Fb"),
client.patch("/_site/api/files/x/transaction", json={"name": "y.mp4"})):
assert r.status_code == 404
assert len(zl.calls) == before