Ash FrameworkAF
Ash Framework5mo ago
46 replies
thinklt

Not sure how to apply a policy on an attribute of a resource. Keep getting an error.

I have a policy for a resource called user_tokens which is just a way to test a user sign up. User enters phone number and user_tokens will save and send an otp to the mobile number. To avoid abuse, there is a status column which when "locked" should stop sending the SMS. I tried the things as the error suggested but could not overcome the problem yet. Also searched the prior posts but yet to find an answer. Very new to Ash, but hopefully I am not bugging and taking up much of your time in the process of getting past my learning curve. Apologies if I am.

policy action_type([:create]) do
      forbid_if expr(status == :locked)
      authorize_if always()
    end


iex(1)> Ash.Changeset.for_create(Arrive.Account.UserToken, :send_otp, %{sent_to: "1112223333"}) |> Ash.create!()
** (Ash.Error.Forbidden)
Bread Crumbs:
  > Exception raised in: Arrive.Account.UserToken.send_otp

Forbidden Error

* Cannot use a filter to authorize a create.

Filter: not status == :locked

If you are using Ash.Policy.Authorizer:

  Many expressions, like those that reference relationships, require using custom checks when used with create actions.

  Expressions that only reference the actor or context, for example `expr(^actor(:is_admin) == true)` will work
  because those are evaluated without needing to reference data.

  For create actions, there is no data yet. In the future we may support referencing simple attributes and those
  references will be referring to the values of the data about to be created, but at this time we do not.

  Given a policy like:

      policy expr(special == true) do
        authorize_if expr(allows_special == true)
      end

  You would rewrite it to not include create actions like so:

      policy [expr(special == true), action_type([:read, :update, :destroy])] do
        authorize_if expr(allows_special == true)
      end
Was this page helpful?