From 9d5a369ff6aa2dc3a80f104ffdc622ddf594a725 Mon Sep 17 00:00:00 2001 From: Logan Hunt Date: Wed, 13 Apr 2022 12:42:01 -0600 Subject: [PATCH] Add guards on post resources --- lib/aggiedit/roles.ex | 10 ++++++++ lib/aggiedit_web/live/post_live/index.ex | 24 +++++++++++++++---- lib/aggiedit_web/live/post_live/show.ex | 24 ++++++++++++++----- .../live/post_live/show.html.heex | 1 + ...0220405071636_create_users_auth_tables.exs | 2 +- 5 files changed, 50 insertions(+), 11 deletions(-) create mode 100644 lib/aggiedit/roles.ex diff --git a/lib/aggiedit/roles.ex b/lib/aggiedit/roles.ex new file mode 100644 index 0000000..e50b53b --- /dev/null +++ b/lib/aggiedit/roles.ex @@ -0,0 +1,10 @@ +defmodule Aggiedit.Roles do + alias Aggiedit.Accounts.User + alias Aggiedit.Rooms.Post + + def guard?(user, action, object) + def guard?(%User{role: :admin}, _, _), do: true + def guard?(%User{room_id: rid}, :show, %Post{room_id: rid}), do: true + def guard?(%User{id: id, room_id: rid}, action, %Post{user_id: id, room_id: rid}) when action in [:delete, :edit], do: true + def guard?(_, _, _), do: false +end \ No newline at end of file diff --git a/lib/aggiedit_web/live/post_live/index.ex b/lib/aggiedit_web/live/post_live/index.ex index 7f3ac65..d48ce67 100644 --- a/lib/aggiedit_web/live/post_live/index.ex +++ b/lib/aggiedit_web/live/post_live/index.ex @@ -1,6 +1,7 @@ defmodule AggieditWeb.PostLive.Index do use AggieditWeb, :live_view + alias Aggiedit.Roles alias Aggiedit.Rooms alias Aggiedit.Rooms.Post alias Aggiedit.Repo @@ -14,12 +15,24 @@ defmodule AggieditWeb.PostLive.Index do end end + @impl true + def handle_params(%{"id" => id}=params, _url, socket) do + post = Rooms.get_post!(id) + if Roles.guard?(socket.assigns.current_user, socket.assigns.live_action, post) do + {:noreply, apply_action(socket, socket.assigns.live_action, params)} + else + {:noreply, socket |> put_flash(:error, "You do not have permission to edit this post.") |> redirect(to: Routes.post_index_path(socket, :index))} + end + end + @impl true def handle_params(params, _url, socket) do + IO.puts(inspect(params)) {:noreply, apply_action(socket, socket.assigns.live_action, params)} end - defp apply_action(socket, :edit, %{"id" => id}) do + + defp apply_action(socket, :edit, %{"id" => id}=params) do socket |> assign(:page_title, "Edit Post") |> assign(:post, Rooms.get_post!(id) |> Repo.preload(:upload)) @@ -40,9 +53,12 @@ defmodule AggieditWeb.PostLive.Index do @impl true def handle_event("delete", %{"id" => id}, socket) do post = Rooms.get_post!(id) - {:ok, _} = Rooms.delete_post(post) - - {:noreply, assign(socket, :posts, list_posts())} + if Roles.guard?(socket.assigns.current_user, :delete, post) do + Rooms.delete_post(post) + {:noreply, socket |> put_flash(:success, "Post deleted.") |> redirect(to: Routes.post_index_path(socket, :index))} + else + {:noreply, socket |> put_flash(:error, "You do not have permission to delete this post.") |> redirect(to: Routes.post_index_path(socket, :index))} + end end defp list_posts do diff --git a/lib/aggiedit_web/live/post_live/show.ex b/lib/aggiedit_web/live/post_live/show.ex index 2416156..748c6ea 100644 --- a/lib/aggiedit_web/live/post_live/show.ex +++ b/lib/aggiedit_web/live/post_live/show.ex @@ -2,18 +2,30 @@ defmodule AggieditWeb.PostLive.Show do use AggieditWeb, :live_view alias Aggiedit.Rooms + alias Aggiedit.Roles + alias Aggiedit.Repo @impl true - def mount(_params, _session, socket) do - {:ok, socket} + def mount(_params, session, socket) do + socket = assign_socket_user(session, socket) + case socket.assigns do + %{:current_user => user} -> {:ok, socket} + _ -> {:ok, socket |> put_flash(:error, "You must log in to access this page.") |> redirect(to: Routes.user_session_path(socket, :new))} + end end @impl true def handle_params(%{"id" => id}, _, socket) do - {:noreply, - socket - |> assign(:page_title, page_title(socket.assigns.live_action)) - |> assign(:post, Rooms.get_post!(id))} + post = Rooms.get_post!(id) + |> Repo.preload(:upload) + if Roles.guard?(socket.assigns.current_user, socket.assigns.live_action, post) do + {:noreply, + socket + |> assign(:page_title, page_title(socket.assigns.live_action)) + |> assign(:post, post)} + else + {:noreply, socket |> put_flash(:error, "You don't have permission to do that.") |> redirect(to: Routes.post_show_path(socket, :index))} + end end defp page_title(:show), do: "Show Post" diff --git a/lib/aggiedit_web/live/post_live/show.html.heex b/lib/aggiedit_web/live/post_live/show.html.heex index e6eaebe..fd57bbb 100644 --- a/lib/aggiedit_web/live/post_live/show.html.heex +++ b/lib/aggiedit_web/live/post_live/show.html.heex @@ -5,6 +5,7 @@ <.live_component module={AggieditWeb.PostLive.FormComponent} id={@post.id} + current_user={@current_user} title={@page_title} action={@live_action} post={@post} diff --git a/priv/repo/migrations/20220405071636_create_users_auth_tables.exs b/priv/repo/migrations/20220405071636_create_users_auth_tables.exs index 06bde64..c7a2126 100644 --- a/priv/repo/migrations/20220405071636_create_users_auth_tables.exs +++ b/priv/repo/migrations/20220405071636_create_users_auth_tables.exs @@ -14,7 +14,7 @@ defmodule Aggiedit.Repo.Migrations.CreateUsersAuthTables do timestamps() end - create unique_index(:users, [:email]) + create unique_index(:users, [:email, :username]) create table(:users_tokens) do add :user_id, references(:users, on_delete: :delete_all), null: false