neiam
/apollos_crib
It's Apollo's Crib
public · Issues · Pulls 1 · Labels · Forks · Compare · Actions failure · Badges · Packages
⭐
Log in to mark this repository.
Ankyra: the ankyra pages only reach the user's own
d3734b5 · Gabe Morell · 2026-11-04 22:11
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