defmodule DexiWeb.UserAuth do @moduledoc false use DexiWeb, :verified_routes import Plug.Conn import Phoenix.Controller alias Dexi.Accounts alias Dexi.Accounts.Scope def fetch_current_scope(conn, _opts) do user = conn |> get_session(:user_pubkey) |> Accounts.get_user_by_pubkey() assign(conn, :current_scope, Scope.for_user(user)) end def log_in_user(conn, user) do delete_csrf_token() conn |> configure_session(renew: true) |> clear_session() |> put_session(:user_pubkey, user.pubkey) end def log_out_user(conn) do if live_socket_id = get_session(conn, :live_socket_id) do DexiWeb.Endpoint.broadcast(live_socket_id, "disconnect", %{}) end delete_csrf_token() conn |> configure_session(renew: true) |> clear_session() end def require_authenticated_user(conn, _opts) do if conn.assigns.current_scope.user do conn else conn |> put_flash(:error, "Log in to continue.") |> redirect(to: ~p"/login") |> halt() end end def require_admin(conn, _opts) do case conn.assigns.current_scope.user do %{role: :admin} -> conn _not_admin -> conn |> put_flash(:error, "You do not have access to that page.") |> redirect(to: ~p"/") |> halt() end end def on_mount(:mount_current_scope, _params, session, socket) do {:cont, mount_current_scope(socket, session)} end def on_mount(:require_authenticated, _params, session, socket) do socket = mount_current_scope(socket, session) if socket.assigns.current_scope.user do {:cont, socket} else {:halt, socket |> Phoenix.LiveView.put_flash(:error, "Log in to continue.") |> Phoenix.LiveView.redirect(to: ~p"/login")} end end def on_mount(:require_admin, _params, session, socket) do socket = mount_current_scope(socket, session) case socket.assigns.current_scope.user do %{role: :admin} -> {:cont, socket} _not_admin -> {:halt, socket |> Phoenix.LiveView.put_flash(:error, "You do not have access to that page.") |> Phoenix.LiveView.redirect(to: ~p"/")} end end defp mount_current_scope(socket, session) do Phoenix.Component.assign_new(socket, :current_scope, fn -> user = session |> Map.get("user_pubkey") |> Accounts.get_user_by_pubkey() Scope.for_user(user) end) end end