1.2 KiB · text History b868907
defmodule GitGudWeb.OrgAdmin do
  @moduledoc """
  `GitGudWeb.RepoAdmin`'s counterpart for organization settings pages.

  Each page checks `Organizations.org_admin?/2` in mount; every handler
  that changes something goes through `with_org_admin/2`, which re-reads
  the organization and the membership rather than trusting the mount —
  an admin demoted in another tab keeps no powers in this one.
  """

  import Phoenix.LiveView, only: [put_flash: 3]

  alias GitGud.Organizations
  alias GitGud.Organizations.Organization

  @doc "Whether the socket's user administers its `:org`, asked now."
  def org_admin_now?(%{assigns: %{org: %Organization{id: id}} = assigns}) do
    user = assigns[:current_scope] && assigns.current_scope.user

    case user && GitGud.Repo.get(Organization, id) do
      %Organization{} = org -> Organizations.org_admin?(org, user)
      _ -> false
    end
  end

  def org_admin_now?(_socket), do: false

  @doc """
  Runs `fun` (a handler body returning `{:noreply, socket}`) only if the
  socket's user still administers the organization.
  """
  def with_org_admin(socket, fun) when is_function(fun, 0) do
    if org_admin_now?(socket),
      do: fun.(),
      else: {:noreply, put_flash(socket, :error, "Org admin only.")}
  end
end