Ankyra: the ankyra pages only reach the user's own

d3734b5 · Gabe Morell · 2026-11-04 22:11

14 files +54 -3
Message
{commit_body(@commit)}

Files changed

modified apps/room_sanctum/lib/room_sanctum/accounts.ex
+3 −0
@@ -44,6 +44,9 @@ defmodule RoomSanctum.Accounts do
44 44 """
45 45 def get_rabbit_user!(id), do: Repo.get!(RabbitUser, id)
46 46
47 + # Someone else's raises the not-found a missing one does.
48 + def get_rabbit_user!({:user, uid}, id), do: Repo.get_by!(RabbitUser, id: id, user_id: uid)
49 +
47 50 @doc """
48 51 Creates a rabbit_user.
49 52
modified apps/room_sanctum/lib/room_sanctum_web/live/cfg_ankyra/index.ex
+5 −2
@@ -19,7 +19,7 @@ defmodule RoomSanctumWeb.AnkyraLive.Index do
19 19 defp apply_action(socket, :edit, %{"id" => id}) do
20 20 socket
21 21 |> assign(:page_title, "Modify Ankyra")
22 − |> assign(:ankyra, Accounts.get_rabbit_user!(id))
22 + |> assign(:ankyra, Accounts.get_rabbit_user!(owner(socket), id))
23 23 end
24 24
25 25 defp apply_action(socket, :new, _params) do
@@ -41,7 +41,7 @@ defmodule RoomSanctumWeb.AnkyraLive.Index do
41 41
42 42 @impl true
43 43 def handle_event("delete", %{"id" => id}, socket) do
44 − ankyra = Accounts.get_rabbit_user!(id)
44 + ankyra = Accounts.get_rabbit_user!(owner(socket), id)
45 45 {:ok, _} = Accounts.delete_rabbit_user!(ankyra)
46 46
47 47 {:noreply, stream_delete(socket, :ankyras, ankyra)}
@@ -55,4 +55,7 @@ defmodule RoomSanctumWeb.AnkyraLive.Index do
55 55 defp list_ankyras(uid) do
56 56 Accounts.list_users_rabbit({:user, uid})
57 57 end
58 +
59 + # Ids from the URL or the client are looked up among the user's own.
60 + defp owner(socket), do: {:user, socket.assigns.current_user.id}
58 61 end
modified apps/room_sanctum/lib/room_sanctum_web/live/cfg_ankyra/show.ex
+5 −1
@@ -22,7 +22,7 @@ defmodule RoomSanctumWeb.AnkyraLive.Show do
22 22 {:noreply,
23 23 socket
24 24 |> assign(:page_title, page_title(socket.assigns.live_action))
25 − |> assign(:ankyra, Accounts.get_rabbit_user!(id))
25 + |> assign(:ankyra, Accounts.get_rabbit_user!(owner(socket), id))
26 26 |> then(&assign_pairing(&1, &1.assigns.broker))}
27 27 end
28 28
@@ -53,6 +53,7 @@ defmodule RoomSanctumWeb.AnkyraLive.Show do
53 53 @impl true
54 54 def handle_event("toggle-auto-register", _params, socket) do
55 55 ankyra = socket.assigns.ankyra
56 +
56 57 {:ok, updated} =
57 58 Accounts.update_rabbit_user(ankyra, %{auto_register_clients: !ankyra.auto_register_clients})
58 59
@@ -186,4 +187,7 @@ defmodule RoomSanctumWeb.AnkyraLive.Show do
186 187
187 188 defp page_title(:show), do: "Ankyra Detail"
188 189 defp page_title(:edit), do: "Modify Ankyra"
190 +
191 + # The Ankyra comes from the URL, so it is looked up among the user's own.
192 + defp owner(socket), do: {:user, socket.assigns.current_user.id}
189 193 end
modified apps/room_sanctum/test/room_sanctum_web/live/ownership_test.exs
+41 −0
@@ -428,4 +428,45 @@ defmodule RoomSanctumWeb.OwnershipTest do
428 428 assert Repo.reload(theirs)
429 429 end
430 430 end
431 +
432 + defp ankyra_for(user) do
433 + {:ok, ankyra} =
434 + Accounts.create_rabbit_user(%{
435 + username: Ecto.UUID.generate(),
436 + password: "hunter2",
437 + topic: "Their-Topic",
438 + user_id: user.id
439 + })
440 +
441 + ankyra
442 + end
443 +
444 + describe "the ankyra pages" do
445 + setup :users_rabbit!
446 +
447 + test "will not show another user's ankyra", ctx do
448 + theirs = ankyra_for(ctx.them)
449 +
450 + assert_raise Ecto.NoResultsError, fn ->
451 + live(ctx.conn, Routes.ankyra_show_path(ctx.conn, :show, theirs))
452 + end
453 + end
454 +
455 + test "will not open another user's ankyra for editing", ctx do
456 + theirs = ankyra_for(ctx.them)
457 +
458 + assert_raise Ecto.NoResultsError, fn ->
459 + live(ctx.conn, Routes.ankyra_index_path(ctx.conn, :edit, theirs))
460 + end
461 + end
462 +
463 + test "will not delete another user's ankyra", ctx do
464 + theirs = ankyra_for(ctx.them)
465 + {:ok, live, _html} = live(ctx.conn, Routes.ankyra_index_path(ctx.conn, :index))
466 +
467 + forge(live, "delete", %{"id" => to_string(theirs.id)})
468 +
469 + assert Repo.reload(theirs)
470 + end
471 + end
431 472 end

Parents: f2c072f