diff --git a/lib/nerves_hub/accounts.ex b/lib/nerves_hub/accounts.ex index 61408a7c3..7b4baf5b8 100644 --- a/lib/nerves_hub/accounts.ex +++ b/lib/nerves_hub/accounts.ex @@ -130,12 +130,9 @@ defmodule NervesHub.Accounts do end def get_org_user(org, user) do - from( - ou in OrgUser, - where: - ou.org_id == ^org.id and - ou.user_id == ^user.id - ) + OrgUser + |> where([ou], ou.org_id == ^org.id) + |> where([ou], ou.user_id == ^user.id) |> OrgUser.with_user() |> Repo.exclude_deleted() |> Repo.one() diff --git a/lib/nerves_hub_web.ex b/lib/nerves_hub_web.ex index 43807b877..847c6d846 100644 --- a/lib/nerves_hub_web.ex +++ b/lib/nerves_hub_web.ex @@ -116,6 +116,8 @@ defmodule NervesHubWeb do # Translation import NervesHubWeb.Gettext + import NervesHub.Helpers.Authorization + # Shortcut for generating JS commands alias Phoenix.LiveView.JS diff --git a/lib/nerves_hub_web/helpers/authorization.ex b/lib/nerves_hub_web/helpers/authorization.ex new file mode 100644 index 000000000..66be49c28 --- /dev/null +++ b/lib/nerves_hub_web/helpers/authorization.ex @@ -0,0 +1,17 @@ +defmodule NervesHub.Helpers.Authorization do + alias NervesHub.Accounts.OrgUser + alias NervesHub.Accounts.User + + def authorized!(org_user, permission) do + true = authorized?(org_user, permission) + end + + def authorized?(:update_product, %OrgUser{role: user_role}), do: role_check(:write, user_role) + def authorized?(:delete_product, %OrgUser{role: user_role}), do: role_check(:admin, user_role) + + defp role_check(required_role, user_role) do + required_role + |> User.role_or_higher() + |> Enum.any?(&(&1 == user_role)) + end +end diff --git a/lib/nerves_hub_web/live/product/settings.ex b/lib/nerves_hub_web/live/product/settings.ex index 8eb6e33d2..2a6785bf6 100644 --- a/lib/nerves_hub_web/live/product/settings.ex +++ b/lib/nerves_hub_web/live/product/settings.ex @@ -15,6 +15,8 @@ defmodule NervesHubWeb.Live.Product.Settings do end def handle_event("delta-updated", %{"delta_updatable" => delta}, socket) do + authorized!(:update_product, socket.assigns.org_user) + attrs = %{delta_updatable: delta == "true"} {:ok, product} = Products.update_product(socket.assigns.product, attrs) @@ -23,6 +25,8 @@ defmodule NervesHubWeb.Live.Product.Settings do end def handle_event("add-shared-secret", _params, socket) do + authorized!(:update_product, socket.assigns.org_user) + {:ok, _} = Products.create_shared_secret_auth(socket.assigns.product) refreshed = Products.load_shared_secret_auth(socket.assigns.product) @@ -40,6 +44,8 @@ defmodule NervesHubWeb.Live.Product.Settings do end def handle_event("deactivate-shared-secret", %{"shared_secret_id" => shared_secret_id}, socket) do + authorized!(:update_product, socket.assigns.org_user) + product = socket.assigns.product {:ok, _} = Products.deactivate_shared_secret_auth(product, shared_secret_id) @@ -48,4 +54,17 @@ defmodule NervesHubWeb.Live.Product.Settings do {:reply, assign(socket, :shared_secrets, refreshed.shared_secret_auth)} end + + def handle_event("delete-product", _parmas, socket) do + authorized!(:delete_product, socket.assigns.org_user) + + with {:ok, _product} <- Products.delete_product(socket.assigns.product) do + socket = + socket + |> put_flash(:info, "Product deleted successfully.") + |> redirect(to: "/org/#{socket.assigns.org.name}") + + {:noreply, socket} + end + end end diff --git a/lib/nerves_hub_web/live/product/settings.html.heex b/lib/nerves_hub_web/live/product/settings.html.heex index 4a2809a19..e518f3cc7 100644 --- a/lib/nerves_hub_web/live/product/settings.html.heex +++ b/lib/nerves_hub_web/live/product/settings.html.heex @@ -27,7 +27,16 @@