AshAuthenticationPhoenix Override Register Form

I want to add a form field on the register form, specifically tenant information for attribute based multitenancy. I see that there is a register_extra slot which receives the form, so I was thinking I could use that. Is there a way to override just the Password.RegisterForm to a custom component (assuming that is how I'd add the slot)?
4 Replies
gvanders
gvandersOP3y ago
For completeness, the way I achieved this was by making a custom SignInLive, which was basically a copy of SignIn component in AshAuthentication.Phoenix, just with <:registry_extra> used in the strategy slot. I did not end up sticking with this, and instead created a default tenant on sign-in via
create :register_with_tenant do
accept([:email])
argument(:password, :string, allow_nil?: false, sensitive?: true)
argument(:password_confirmation, :string, allow_nil?: true, sensitive?: true)
change({AshAuthentication.Strategy.Password.HashPasswordChange, strategy_name: :password})
change({AshAuthentication.GenerateTokenChange, strategy_name: :password})

validate(AshAuthentication.Strategy.Password.PasswordConfirmationValidation)

change(fn changeset, _ ->
Ash.Changeset.manage_relationship(changeset, :organization, %{}, type: :create)
end)
end
create :register_with_tenant do
accept([:email])
argument(:password, :string, allow_nil?: false, sensitive?: true)
argument(:password_confirmation, :string, allow_nil?: true, sensitive?: true)
change({AshAuthentication.Strategy.Password.HashPasswordChange, strategy_name: :password})
change({AshAuthentication.GenerateTokenChange, strategy_name: :password})

validate(AshAuthentication.Strategy.Password.PasswordConfirmationValidation)

change(fn changeset, _ ->
Ash.Changeset.manage_relationship(changeset, :organization, %{}, type: :create)
end)
end
signed in with this action
read :sign_in_with_tenant do
# argument(:email, Ash.Type.CiString, allow_nil?: false)
get? true
# argument(:password, :string, allow_nil?: false, sensitive?: true)

# prepare(AshAuthentication.Strategy.Password.SignInPreparation)
prepare(build(load: [:organization]))
end
read :sign_in_with_tenant do
# argument(:email, Ash.Type.CiString, allow_nil?: false)
get? true
# argument(:password, :string, allow_nil?: false, sensitive?: true)

# prepare(AshAuthentication.Strategy.Password.SignInPreparation)
prepare(build(load: [:organization]))
end
With these options
get_by_subject_action_name :sign_in_with_tenant
strategies do
password :password do
identity_field(:email)
register_action_name(:register_with_tenant)
end
get_by_subject_action_name :sign_in_with_tenant
strategies do
password :password do
identity_field(:email)
register_action_name(:register_with_tenant)
end
Really loved how the custom actions were validated! Was not expecting that and was able to just follow the error messages for what I was missing @jart
jart
jart3y ago
That’s great news. I’m glad you were able to get where you needed and this is basically what I would have advised you to do. If you have any suggestions on how to make the docs better so you can achieve this result quicker I’d love to hear it.
gvanders
gvanders3y ago
Possibly just a section on the three action override DSLs, and what part of the lifecycle they hook into. Once I realized that register_action_name and sign_in_action_name existed I was good, though I assumed sign_in was the action that would be used when trying to put the user and tenant in conn. I later found out that it was get_by_subject_action_name which is outside the strategies DSL documentation
jart
jart3y ago
Right. I’ll look at how to add this to the guide today.

Did you find this page helpful?