There are more than a few different ways you could do that. The simplest one would be to modify the actions that are created, by defining them yourself or adding behavior to them.
- creating them yourself, if you do this, AshAuthentication will just validate that the action contains the correct elements:
read :sign_in_with_password do
...
# can also put it in a module: prepare RequireGoogleSignInForFoo
prepare fn query, result ->
if is_foo(Ash.Changeset.get_argument(query, :email)) do
Ash.Query.add_error(query, field: :email, message: "your organization requires google sign in")
else
query
end
end
end
```elixir
2. Add a preparation at the resource level that will apply to all actions, but filter it to apply to only a given action (this allows you to modify a single action without redefining it yourself.
```elixir
preparations do
prepare RequireGoogleSignInForFoo, where: action_is(:sign_in_with_password)
endAt the end of the day, you only need to use as much of the tooling as is useful for you. The prebuilt pages and components are a great starting point, but they can always be replaced by your own stuff if modifying them by overriding components/classes proves to cumbersome. The same goes for the actions that run your authentication flow. You can overwrite them, or add modifications.
In Ash, actions are handled similarly to Plug.Conn, in that you are given functional hooks to modify your data structure, which is either a changeset or a query depending on the action type. And within that structure, you have tons of options.