Where is the best place to put the permissions checking logic in LiveView?

Ahh, that is unfortunate… Funnily enough, your profile picture just reminded where I likely got the idea from in the first place.

So I’m guessing you’re speaking from hard earned experience!

Agreed, this is how it was addressed in the security considerations docs @wanton7 linked above.

Project.delete!(socket.assigns.current_user, project_id)

It could be nice to use function arity to support actions with or without a user parameter for permission checking since traditional controllers can be protected by plugs. Maybe something like this assuming there’s a Blog Context:

defmodule MyApp.Blog do
  def update_post(%User{} = user, post, post_params) do
    with :ok <- Bodyguard.permit(MyApp.Blog, :update_post, user, post),
      do: MyApp.Blog.update_post(post, post_params)
  end

  def update_post(%Post{} = post, attrs) do
    post
    |> Post.changeset(attrs)
    |> Repo.update()
  end
end

One consideration when relying solely on the LiveView handle_event callback would be that all operations would need to go through the LiveView. That would mean the LiveView can potentially get very cluttered with event callbacks. Take the out of the box form components generated by mix phx.gen.live for example, you would need to move all the calls to Context functions in the event callbacks to the parent LiveView.

1 Like