AE
Ash Elixir•3y ago
Jmanda

Override/Extend AshAuthentication Sign in

On submitting user credentials, I want to do something(like a query on some resource) before user email and password validation, and if its successful I want put some stuff in the Process dictionary. How can I override/extend/hook-into the sign in actions in AshAuthentication? I know a can set stuff into the Process dictionary in the handle_success callback, but don't know where to put the other implementations. Thank you.
4 Replies
ZachDaniel
ZachDaniel•3y ago
You can add a preparation that checks the action and adds an after action hook There is a global preparations block
preparations do
prepare fn query, _ ->
if query.action.name ==
end
end
preparations do
prepare fn query, _ ->
if query.action.name ==
end
end
Jmanda
JmandaOP•3y ago
Thank you Zach, I will try that @Zach Daniel I managed to implement that and it worked. However I have an issue, the current user is missing in the liveview socket I have set the on_mount: callback like this:
defmodule MyAppWeb.LiveUserAuth do
def on_mount(:live_user_required, _params, %{"tenant" => tenant} = _session, socket) do
Ash.set_tenant(tenant)
IO.inspect(socket, label: "socket")

if socket.assigns[:current_user] do
{:cont, socket}
else
{:halt, Phoenix.LiveView.redirect(socket, to: "/sign-in")}
end
end
end
defmodule MyAppWeb.LiveUserAuth do
def on_mount(:live_user_required, _params, %{"tenant" => tenant} = _session, socket) do
Ash.set_tenant(tenant)
IO.inspect(socket, label: "socket")

if socket.assigns[:current_user] do
{:cont, socket}
else
{:halt, Phoenix.LiveView.redirect(socket, to: "/sign-in")}
end
end
end
And in the router.ex
scope "/", MyAppWeb do
pipe_through :browser

ash_authentication_live_session :ash_authentication,
on_mount: {MyAppWeb.LiveUserAuth, :live_user_required} do
live "/", DashboardLive.Index, :index
...
end
end
scope "/", MyAppWeb do
pipe_through :browser

ash_authentication_live_session :ash_authentication,
on_mount: {MyAppWeb.LiveUserAuth, :live_user_required} do
live "/", DashboardLive.Index, :index
...
end
end
* note that am setting the tenant, as the user is not on the public schema So whats happening is that when the liveview mounts(first time when socket not connected), the socket has a current_user, cause the tenant is the Process, however when the liveview is mounted again(when socket is connected), the socket does not have a current_user assigned, probably because the liveview is now in a new PID, where tenant is not set, resulting the user query running on the public_schema instead of a tenant schema. Is there a way I can resolve this?
ZachDaniel
ZachDaniel•3y ago
I generally suggest not using set_tenant and friends for this reason. Your best bet is to assign the tenant and use it in all your calls to Changeset.for_create and the other action builders. You can also just assign the tenant and call set_tenant in the liveview mount instead
Jmanda
JmandaOP•3y ago
Okay will do that. Thanks for the help once again 😃

Did you find this page helpful?