Ash FrameworkAF
Ash Framework3y ago
8 replies
Alan Heywood

relates_to_actor_attribute_via

I have a resource called Actor that is not backed by the database, it looks something like this:

defmodule Ht.Actor do
  use Ash.Resource, data_layer: Ash.DataLayer.Ets
    
  relationships do
    belongs_to :user, Ht.User
    belongs_to :role, Ht.Role
  end
end


The user will always be set, and the role will sometimes be set.

I want to be able to write policies for both cases. What I have done up until now is pass either the user or the role to Ash.PlugHelpers.set_actor(), which lets me write policies like this:

  policies do
    bypass Ht.Policy.Checks.actor_is(Ht.User) do
      authorize_if action_type(:read) && relates_to_actor_via([:accounts, :user])
    end

    bypass Ht.Policy.Checks.actor_is(Ht.Role) do
      authorize_if action_type(:read) && relates_to_actor_via([:accounts, :roles])
    end

    policy always() do
      forbid_if always()
    end
  end


My preferred choice has always been to pass the actual actor record to Ash.PlugHelpers.set_actor() instead of user or role, however I wasn't able to get this to work with relates_to_actor_via.

I now need to add more data to my Actor resource, and have it available in a custom read, so I am looking for a way to make it work.

First I looked for a way to set some context at the same place I call set_actor however it looks like that context is not passed into a custom read.

I am considering a new check relates_to_actor_attribute_via. That way I can pass my full actor record to set_actor and write my policies on the necessary actor attribute.

The other possible solution is having a way to specify arbitrary context on the connection that is passed to read actions, etc in the same way actor is.

Any thoughts on these approaches?
Was this page helpful?