How to use arguments in policies

I have a rooms has_many members situation in which I want to authorize joining a room if the user has its invite code, but I can't seem to make it work, even after repeatedly reading through the docs, example apps and source code. The room resource looks like this:
policies do
bypass action_type(:create) do
authorize_if always()
end

bypass action(:join) do
authorize_if expr(invite_code == ^arg(:invite_code))
end

policy always() do
authorize_if expr(exists(members, id == ^actor(:id)))
end
end
...
actions do
defaults [:update, :destroy]

read :read do
primary? true
end

create :create do
accept [:name]
end

update :join do
argument :name, :string do
allow_nil? false
end

argument :invite_code, :uuid do
allow_nil? false
end

change manage_relationship :name, :members,
value_is_key: :name,
type: :create
end
end
policies do
bypass action_type(:create) do
authorize_if always()
end

bypass action(:join) do
authorize_if expr(invite_code == ^arg(:invite_code))
end

policy always() do
authorize_if expr(exists(members, id == ^actor(:id)))
end
end
...
actions do
defaults [:update, :destroy]

read :read do
primary? true
end

create :create do
accept [:name]
end

update :join do
argument :name, :string do
allow_nil? false
end

argument :invite_code, :uuid do
allow_nil? false
end

change manage_relationship :name, :members,
value_is_key: :name,
type: :create
end
end
The member resource authorizes everything:
policies do
policy always() do
authorize_if always()
end
end

actions do
defaults [:read, :create, :update, :destroy]
end

attributes do
uuid_primary_key :id

attribute :room_id, :uuid do
allow_nil? false
end

attribute :name, :string do
allow_nil? false
end

timestamps()
end
policies do
policy always() do
authorize_if always()
end
end

actions do
defaults [:read, :create, :update, :destroy]
end

attributes do
uuid_primary_key :id

attribute :room_id, :uuid do
allow_nil? false
end

attribute :name, :string do
allow_nil? false
end

timestamps()
end
This is what I get when trying to join a room: (message is too long, see attachment) I'm not sure why it first says Successful authorization and then forbidden. I'm not sure if I'm missing something to make the argument available to the policy, or if I should be using validations instead, or something completely different. Thanks in advance
2 Replies
ZachDaniel
ZachDaniel3y ago
This is likely an oversight in the way we build expressions for policies. You cannot reference args like that. You need to write a simple check or filter check and use that in place of an expression.
Ash HQ Bot
Ash HQ Bot3y ago
Ash HQ
Module: Ash.Policy.SimpleCheck
View the documentation for Ash.Policy.SimpleCheck on Ash HQ.
Ash HQ
Module: Ash.Policy.Check
View the documentation for Ash.Policy.Check on Ash HQ.

Did you find this page helpful?