Register new Pow User schema through `iex -S mix`

Hello mates.

I’m starting doing a small app to learn about Elixir and Phoenix and.

In my app, I would like to have a User schema with name, email, password and a field to set a role for the user.

To handle the auth stuff I was thinking about using #pow and following the documentation I was able to register a user into an app, so far so good. When I register a new user through the view I just need to set an email and a password (this password will be manipulated to create a password_hash field and be set on the database) and by default, I set this user as a “regular_user” as role.

My problem/question is, how can I create a user directly using iex -S mix to set it as an admin?

I got stuck when I try to create using iex -S mix because I was not able to set the password_hash field.

I don’t want to use a form view to create an admin user because I want only a single user as admin, just wanna use the form to register new regular users into my app.

Thank you!

#phoenix #pow #iex

I have the following function im my Users context

 @spec set_admin_role(t()) :: {:ok, t()} | {:error, Ecto.Changeset.t()}
  def set_admin_role(user) do
    |> User.changeset_role(%{role: "admin"})
    |> Repo.update()

After register the first user, I can now call.

Users.list_users |> hd |> Users.set_admin_role()

You can create the first user either by using the web interface or with iex, as @Kurisu shows in his answer below.

The magic happens in the extra changeset-function in User.ex

 @spec changeset_role(Ecto.Schema.t() | Ecto.Changeset.t(), map()) :: Ecto.Changeset.t()
  def changeset_role(user_or_changeset, attrs) do
    |> Ecto.Changeset.cast(attrs, [:role])
    |> Ecto.Changeset.validate_inclusion(:role, ~w(user admin))
1 Like

This should be possible with your User Context.

admin = %{
    email: "some@email",
    password: "some pass",
    confirm_password: "some pass",
    custom_field: "...",
    role: "admin"

{:ok, _user} = UserContext.create_user(admin)

Of course you’ll have to cast the :role in your context module. But there is a security concern here if we use the same Context method for all users. For non admin users for example we don’t want them to controll the role field by submiting for example by some malicious mean a role in their registration form.

That’s why @iboard solution is best. In my case I use differrent Schema/Context for users according to their role so I can set a default value for the role and don’t bother with casting it.

Edit 2:

This might help as well if you’re using POwEmailConfirmation extension.

  alias PowEmailConfirmation.Ecto.Context, as: ConfirmationContext

  {:ok, user} = UserContext.create_user(user)
  ConfirmationContext.confirm_email(user, %{}, otp_app: :my_app, repo: MyApp.Repo)

Thanks, @iboard, and @Kurisu I’m gonna try out these solutions and reply later with my solution!