Can't get policies to work with AshGraphql
moxley7725:
I have an action,
update_customer_registration , which requires a
Customer actor.
My
Customer policy looks like this:
policies do
policy action(:update_customer_registration) do
authorize_if actor_attribute_equals(:__struct__, __MODULE__)
end
endThis works as expected when using the application’s Ash API directly:
customer
|> Ash.Changeset.new()
|> Ash.Changeset.for_update(:update_customer_registration, %{contact_name: "Test Name"},
actor: customer
)
|> Corp.Ash.Api.update!()
Setting
actor to
nil , raises an policy error as expected.
However, it doesn’t seem to work when going through AshGraphql, when the actor is present:
%{
"data" => %{"updateCustomerRegistration" => nil},
"errors" => [%{"code" => "Forbidden", "fields" => [], "locations" => [%{"column" => 5, "line" => 2}], "message" => "forbidden", "path" => ["updateCustomerRegistration"], "short_message" => "forbidden", "vars" => %{}}]
}
I know the actor is being set correctly with
Ash.PlugHelpers.set_actor()
However, when I change the policy to match on any action (
policy always() do ), it works. There seems to be something specific with specifying the action in the policy that doesn’t work with AshGraphql.
_ahey:
Do you have
AshGraphql.Plug in your :api pipeline?
moxley7725:
Yes, I have it in the pipeline
moxley7725:
And I’m calling
Ash.PlugHelpers.set_actor(conn, session_resource) ,
And I inspected
session_resource , and it’s the Customer struct.
_ahey:
My pipeline looks like this:
pipeline :api do
plug(:accepts, ["json"])
plug(:load_from_bearer)
plug(HtWeb.AuthPlug) # Here I am calling Ash.PlugHelpers.set_actor
plug(AshGraphql.Plug) # This is needed as well
endAssuming you have something similar set up, my next steps would be to set the following to see if it offers any more clues.
config :ash, :policies, log_policy_breakdowns: :error
config :ash, :policies, log_successful_policy_breakdowns: :error
moxley7725:
Yes, my pipeline looks similar to that.
moxley7725:
Yes, I’ve set up logging.
moxley7725:
The policy logging doesn’t seem to work when going through AshGraphql through
moxley7725:
When I enable policy logging, it works correctly when I go direct through my Ash API, but when going through GraphQL, this is the only thing that is added to the log output:
[warning] Corp.Customers.Customer.read
moxley7725:
The basic policy integration seems to be working. It just doesn’t work when the policy is specific about which action it applies to.
_ahey:
From memory,
ash_graphql does need to have permission to also
:read the thing it’s updating, could that be it?
moxley7725:
Maybe…
moxley7725:
That was it!
moxley7725:
I needed to add the
:read action to the policy
_ahey:
Great! Glad you got it working. Also I just ran one of my unit tests that uses GQL, and when I turn on the policy logging it does log all the policy logs with breakdown, so i’m not sure why that doesn’t work for you.
moxley7725:
Yeah, I don’t know. That’s strange.
moxley7725:
The other problem I need to solve with this GraphQL query is that it needs to get the Customer from the current actor.
moxley7725:
I was temporarily allowing the request to pass in the Customer ID, but the requirement is that the session token is the only identifying information that will be passed in.
moxley7725:
I’m not sure how to do that.
_ahey:
Does your actor have a relationship to the customer already?
moxley7725:
The actor is the customer
moxley7725:
Do I need to create a new read action to pass the actor along to the
update_customer_registration action?
_ahey:
You can create a new read action that gets the current actor from session. Here is what I have on my
actor resource:
read :current_actor do
get? true
manual Ht.Actor.Actions.CurrentActorRead
enddefmodule Ht.Actor.Actions.CurrentActorRead do
use Ash.Resource.ManualRead
@impl true
def read(_, _, _, %{actor: actor}) when not is_nil(actor) do
{:ok, [actor]}
end
def read(_, _, _, _), do: {:ok, []}
endThen in your graphql definition:
mutations do
update :update do
identity false
read_action :current_actor
end
...
moxley7725:
Nice! I’ll try that.
moxley7725:
Wow, it worked!
moxley7725:
Thanks <@717986162282725387> !
_ahey:
You’re welcome!