less angry

da770be · gmorell · 2026-06-11 17:04

8 files +20 -21

Files changed

modified lib/oh_my_ex_oh_ircd_web/controllers/scrobble_controller.ex
+5 −8
@@ -51,15 +51,12 @@ defmodule OhMyExOhIrcdWeb.ScrobbleController do
51 51 defp respond(conn, {:error, _}),
52 52 do: conn |> put_status(:service_unavailable) |> json(%{error: "service_unavailable"})
53 53
54 − ## Validation — only who/artist/track/album, non-blank strings, capped,
55 − ## with control chars stripped so nothing can forge an IRC line.
54 + ## Validation — pick out artist/track/album (non-blank strings, capped,
55 + ## with control chars stripped so nothing can forge an IRC line). Any
56 + ## other keys in the body (including a client-supplied `who`, which is
57 + ## token-bound) are ignored.
56 58
57 − defp validate(params) when is_map(params) do
58 − case Map.keys(params) -- @allowed do
59 − [] -> validate_fields(params)
60 − extra -> {:error, "unexpected fields: #{Enum.join(extra, ", ")}"}
61 − end
62 − end
59 + defp validate(params) when is_map(params), do: validate_fields(params)
63 60
64 61 defp validate(_), do: {:error, "body must be a JSON object"}
65 62
modified test/oh_my_ex_oh_ircd_web/controllers/scrobble_controller_test.exs
+15 −13
@@ -43,26 +43,28 @@ defmodule OhMyExOhIrcdWeb.ScrobbleControllerTest do
43 43 assert body["error"] == "invalid_payload"
44 44 end
45 45
46 − test "rejects a client-supplied who with 422 (who is token-bound)", %{conn: conn, token: token} do
47 − body =
48 − conn
49 − |> auth(token)
50 − |> post(~p"/api/v1/scrobble", Map.put(payload(), "who", "someone-else"))
51 − |> json_response(422)
46 + test "ignores a client-supplied who (who is token-bound)", %{conn: conn, token: token, chan: chan} do
47 + {:ok, _} = Scrobbles.ensure_config(chan)
48 + {:ok, _} = Scrobbles.set_joined(chan, true)
52 49
53 − assert body["error"] == "invalid_payload"
54 − assert body["detail"] =~ "who"
50 + conn = conn |> auth(token) |> post(~p"/api/v1/scrobble", Map.put(payload(), "who", "someone-else"))
51 + assert json_response(conn, 200) == %{"status" => "ok"}
52 +
53 + assert [scrobble] = Scrobbles.recent(chan, 5)
54 + assert scrobble.who == "gmp"
55 55 end
56 56
57 − test "rejects unexpected fields with 422", %{conn: conn, token: token} do
58 − body =
57 + test "ignores unexpected fields", %{conn: conn, token: token, chan: chan} do
58 + {:ok, _} = Scrobbles.ensure_config(chan)
59 + {:ok, _} = Scrobbles.set_joined(chan, true)
60 +
61 + conn =
59 62 conn
60 63 |> auth(token)
61 64 |> post(~p"/api/v1/scrobble", Map.put(payload(), "evil", "\r\nPRIVMSG #x :hax"))
62 − |> json_response(422)
63 65
64 − assert body["error"] == "invalid_payload"
65 − assert body["detail"] =~ "evil"
66 + assert json_response(conn, 200) == %{"status" => "ok"}
67 + assert [_scrobble] = Scrobbles.recent(chan, 5)
66 68 end
67 69
68 70 test "valid token but ScrobbleServ not joined returns 404", %{conn: conn, token: token} do

Parents: ca8ee06