lmendelowski

lmendelowski

Ash Framework: A brief detour into LiveView process shenanigans (page 236)

Hello!
I’m neither an Elixir nor Phoenix or Ash expert, but I believe I found misinformation in the A brief detour into LiveView process shenanigans section in the book. The paragraph describes the authentication process for the LiveView process with Ash.Authentication as follows:

The page liveviews, such as TunezWeb.Artists.ShowLive, get the current user via an on_mount callback set up in your app’s router with ash_authentication_live_session. This callback will read the authentication token stored in the session, load the correct user record, and store it in socket.assigns.

I believe this information is not correct. According to ash_authentication_live_session docs:

Generate a live session wherein all subject assigns are copied from the conn into the socket.

Basically, this function copies all assigns from the conn object. The process of getting user_id from the session and loading it into conn.current_user happens in TunezWeb.Router via plug :load_from_session for the browser pipeline. This function comes from AshAuthentication.Plug.Helpers and is described in the documentation as:

Attempt to retrieve all actors from the connections’ session.

A wrapper around AshAuthentication.Plug.Helpers.retrieve_from_session/2 with the otp_app as extracted from the endpoint.

And if we look at mentioned AshAuthentication.Plug.Helpers.retrieve_from_session/2 function:

Attempt to retrieve all users from the connections’ session.

Iterates through all configured authentication resources for otp_app and retrieves any users stored in the session, loads them and stores them in the assigns under their subject name (with the prefix current_).

If there is no user present for a resource then the assign is set to nil.

PS. Thank you for the book. It’s an excellent resource on Ash Framework!

Most Liked

jamesharton

jamesharton

Hi :waving_hand:

As both a technical reviewer for the book and the author of Ash Authentication this section didn’t jump out at me as wrong - mainly, I suspect, because the memory of all the hoops LiveView forces us to jump through have been suppressed as a self-protection measure.

That said, let’s look at the code:

    # From lib/ash_authentication_phoenix/live_session.ex
    otp_app
    |> AshAuthentication.authenticated_resources()
    |> Stream.map(&{to_string(Info.authentication_subject_name!(&1)), &1})
    |> Enum.reduce(acc, fn {subject_name, resource}, session ->
      case Map.fetch(
             conn.assigns,
             String.to_existing_atom("current_#{subject_name}")
           ) do
        {:ok, user} when is_struct(user, resource) ->
          session
          |> Map.put(subject_name, AshAuthentication.user_to_subject(user))
          |> Map.put("tenant", Ash.PlugHelpers.get_tenant(conn))
          |> Map.put("context", Ash.PlugHelpers.get_context(conn))

        _ ->
          session
          |> Map.put("tenant", Ash.PlugHelpers.get_tenant(conn))
          |> Map.put("context", Ash.PlugHelpers.get_context(conn))
      end
    end)

So you’re right that if there is a current_X assign in the conn then it should be copied into the live session. It also copies what we call the subject (eg user?id=1234) into the session along with the tenant and any extra context.

I think where the confusion comes from is when working with nested live views the session is passed in, but not any of the assigns. This required us to add AshAuthentication.Phoenix.assign_new_resources/2 which can have the side-effect of loading the assigned users from the database if require_token_presence_for_authentication? is set to true.

I guess my answer is “:person_shrugging: you’re both right”

Where Next?

Popular Pragmatic Bookshelf topics Top

brianokken
Many tasks_proj/tests directories exist in chapters 2, 3, 5 that have tests that use the custom markers smoke and get, which are not decl...
New
mikecargal
Title: Hands-On Rust (Chapter 11: prefab) Just played a couple of amulet-less games. With a bit of debugging, I believe that your can_p...
New
Mmm
Hi, build fails on: bracket-lib = “~0.8.1” when running on Mac Mini M1 Rust version 1.5.0: Compiling winit v0.22.2 error[E0308]: mi...
New
alanq
This isn’t directly about the book contents so maybe not the right forum…but in some of the code apps (e.g. turbo/06) it sends a TURBO_ST...
New
jgchristopher
“The ProductLive.Index template calls a helper function, live_component/3, that in turn calls on the modal component. ” Excerpt From: Br...
New
digitalbias
Title: Build a Weather Station with Elixir and Nerves: Problem connecting to Postgres with Grafana on (page 64) If you follow the defau...
New
AufHe
I’m a newbie to Rails 7 and have hit an issue with the bin/Dev script mentioned on pages 112-113. Iteration A1 - Seeing the list of prod...
New
rainforest
Hi, I’ve got a question about the implementation of PubSub when using a Phoenix.Socket.Transport behaviour rather than channels. Before ...
New
mcpierce
@mfazio23 I’ve applied the changes from Chapter 5 of the book and everything builds correctly and runs. But, when I try to start a game,...
New
roadbike
From page 13: On Python 3.7, you can install the libraries with pip by running these commands inside a Python venv using Visual Studio ...
New

Other popular topics Top

Exadra37
Please tell us what is your preferred monitor setup for programming(not gaming) and why you have chosen it. Does your monitor have eye p...
New
AstonJ
Curious to know which languages and frameworks you’re all thinking about learning next :upside_down_face: Perhaps if there’s enough peop...
New
AstonJ
I ended up cancelling my Moonlander order as I think it’s just going to be a bit too bulky for me. I think the Planck and the Preonic (o...
New
mafinar
Crystal recently reached version 1. I had been following it for awhile but never got to really learn it. Most languages I picked up out o...
New
rustkas
Intensively researching Erlang books and additional resources on it, I have found that the topic of using Regular Expressions is either c...
New
New
New
husaindevelop
Inside our android webview app, we are trying to paste the copied content from another app eg (notes) using navigator.clipboard.readtext ...
New
New
New

Latest in Ash Framework

Ash Framework Portal

Sub Categories: