AshStateMachine.Checks.ValidNextState does not block some invalid transition

This is a test code for ash_state_machine.

assert Ashex.can?({object, :progress}, nil) == false

This assertion passes, so I think there is no permission.

assert {:error, %Ash.Error.Forbidden{}} = Ashex.run_update(object, :progress, actor: nil)

But this assertion does not pass, because the Object.progress action fails with Ash.Error.Invalid.
I think action call without permission should return Ash.Error.Forbidden.
And Ash.Error.Invalid looks like a validation error.

Is this a bug?

Ash.can? is “is valid and is allowed” by default. Try using Ash.can and see what kind of error is returned.

“valid” means validity of policies?
Not the validity determined by validations?

I’m referring to the validity of the changeset itself. The reason for this is that validations and changes run before authorization.

Any changes or validations that should run after authorization should use before_action?: true (in the case of validations) or Ash.Changeset.before_action in the case of changes.

I think I have bad understandig at policy and can function.
So I need to study more about them.

I have a small question.
Would you give me a scenario, when does the can function return {:ok, :maybe}?

{:ok, :maybe} would be returned in the case of filter policies on read actions, when the data to be read isn’t provided, and run_queries? is set to false. So to answer we’d have to run the queries, so we’d have to say :maybe.

Thank you for your explanation.

Ok, now I got it about my original question.

My Conclusions

Ash.can

  • return {:ok, true} when policy pass (even if validation fail)
  • return {:ok, false} when policy fail

Error returned by action

  • return Ash.Error.Forbidden when only policy fail
  • return Ash.Error.Invalid when only validation fail
  • return Ash.Error.Invalid when policy and validation fail
  • cannot determine policy passed/failed by error class

Why return Ash.Error.Invalid when policy and validation fail?

Is this correct? @zachdaniel

I got these conclusions with below test codes.

This is my ash_state_machine test code.

And this is my authorization_validation_priority_test.exs.

A better way to phrase this would be that when running the action, policies aren’t run on invalid actions.

1 Like