Pow: PowInvitation: how to create the first user?

Created on 23 Jun 2019  路  9Comments  路  Source: danschultzer/pow

PowInvitation requires an invited_by_id, so how should we create the first user that will invite other users?
My first thought is that one should configure a "first_user", or "super_admin" user in prod.secret.exs so it could be deployed safely. Is this the right approach? For all use cases? Are there other solutions? How would one implement this?

Most helpful comment

You need to pass the Pow configuration there. You can use the same config as what's passed to plug Pow.Plug.Session, usually just being the :otp_app to pull the config from app env:

Pow.Ecto.Context.create(%{email: "[email protected]", password: "mytestpassword", password_confirmation: "mytestpassword"}, otp_app: :my_app)

Note that I also added the required confirm_password in the above params.

All 9 comments

PowInvitation doesn't prevent users from signing up without invitation, so you should be able to create a user just using the registration page. However, if you have locked down registration, then I would create the first user with Pow.Ecto.Context.create/2 in priv/repo/seeds.exs or running in iex on production.

Yeah locked down registration would be the scenario. I can't figure out how to use the second argument "config" in that function?
Pow.Ecto.Context.create(%{email: "[email protected]", password: "mytestpassword"}, ??)

You need to pass the Pow configuration there. You can use the same config as what's passed to plug Pow.Plug.Session, usually just being the :otp_app to pull the config from app env:

Pow.Ecto.Context.create(%{email: "[email protected]", password: "mytestpassword", password_confirmation: "mytestpassword"}, otp_app: :my_app)

Note that I also added the required confirm_password in the above params.

That indeed works fine, thanks!

Hi @danschultzer
I'm trying to create a test user in order to make a assoc with my struct but I can't get through it. What I'm missing?

password_hash = Password.pbkdf2_hash(@password)
      Pow.Ecto.Context.create(%{email: "[email protected]", username: "john.doe", password_hash: password_hash,
      password: "mytestpassword", confirm_password: "mytestpassword"}, otp_app: :myapp)

Error:

  1) test searches create_search/1 with valid data creates a search (MyApp.SearchesTest)
     test/myapp/searches_test.exs:98
     ** (Postgrex.Error) ERROR 42703 (undefined_column) column "username" of relation "users" does not exist

         query: INSERT INTO "users" ("email","email_confirmation_token","password_hash","username","inserted_at","updated_at","id") VALUES ($1,$2,$3,$4,$5,$6,$7)
     code: user = test_user()
     stacktrace:
       (ecto_sql 3.3.4) lib/ecto/adapters/sql.ex:612: Ecto.Adapters.SQL.raise_sql_call_error/1
       (ecto 3.3.3) lib/ecto/repo/schema.ex:655: Ecto.Repo.Schema.apply/4
       (ecto 3.3.3) lib/ecto/repo/schema.ex:263: anonymous fn/15 in Ecto.Repo.Schema.do_insert/4
       (pow 1.0.16) lib/pow/ecto/context.ex:204: Pow.Ecto.Context.do_insert/2
       test/myapp/searches_test.exs:99: (test)

I also tried with all db columns (set as a parameter). I use username as a user field which is working fine in frontend.

tried to use custom config like this:

  alias Ecto.Changeset
  alias Pow.Ecto.{Context, Schema.Password}
  alias Pow.Test.Ecto.{Repo, Users, Users.User, Users.UsernameUser}

  @config [repo: Repo, user: User]
  @username_config [repo: Repo, user: UsernameUser]

Trying to use your test approach but couldn't manage. Also I tried to insert through my repo.. all failed.

You may ignore above and just write a code that help us to create a user for unit tests and for seeding db would be very helpful. Appreciate & thanks in advance.

@nesimtunc You don't have a username column for the users table. To be sure things are working correctly, I would check that:

  1. You got an Ecto migration to adds the username field to users
  2. The test db was created successfully, drop and recreate
  3. :otp_app is the same as the one used in config, e.g. it's :my_app if it's config :my_app, :pow
  4. If test without username works:
    elixir Pow.Ecto.Context.create(%{email: "[email protected]", password: "mytestpassword", password_confirmation: "mytestpassword"}, otp_app: :my_app)

Also you shouldn't set the :password_hash when you call Pow.Ecto.Context.create/2. You should pass the same params as you would do from a form.

I don't know why I was checking _dev db. The test db was out of date ... I thought test re-creates | resets db and applies migrations every time but guess not.

now I can create a user, but when not define :password_hash and confirm_password I get this error.

errors: [
     password_hash: {"can't be blank", [validation: :required]},
     confirm_password: {"not same as password", []}
   ],

I'm able to create a user like this:

password_hash = Password.pbkdf2_hash(@password)

      user =
        Pow.Ecto.Context.create(
          %{
            email: "[email protected]",
            username: "john.doe",
            password_hash: password_hash,
            password: @password,
            confirm_password: @password
          },
          otp_app: :my_app
        )

Yeah, you need to add the password confirmation, but password_hash doesn't do anything. This is sufficient:

        Pow.Ecto.Context.create(
          %{
            email: "[email protected]",
            username: "john.doe",
            password: @password,
            confirm_password: @password
          },
          otp_app: :my_app
        )

And with 1.0.17 you should use password_confirmation instead of confirm_password:

        Pow.Ecto.Context.create(
          %{
            email: "[email protected]",
            username: "john.doe",
            password: @password,
            password_confirmation: @password
          },
          otp_app: :my_app
        )

Yeah after upgraded to the latest version, all is good now! Thanks a lot! @danschultzer

Was this page helpful?
0 / 5 - 0 ratings