pow-auth / pow

Robust, modular, and extendable user authentication system
https://powauth.com
MIT License
1.59k stars 153 forks source link

Crash @missing_field? in Schema.ex #700

Closed alexsysm closed 1 year ago

alexsysm commented 1 year ago
 {:ecto_sql, "~> 3.10"},
  {:postgrex, "~> 0.17.1"},
  {:phoenix_pubsub, "~> 2.1"},
  {:jason, "~> 1.4"},
  {:ecto_psql_extras, "~> 0.7.11"},
  {:pow, "~> 1.0.26"},
  {:uuid, "~> 1.1"},
  {:httpoison, "~> 1.8"},
  {:cloak_ecto, "~> 1.2"},

(base) iex -S mix phx.server

Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:16:16] [ds:16:16:10] [async-threads:1] [jit:ns]

==> hippo_abs Compiling 2 files (.ex)

== Compilation error in file lib/hippo_abs/schema/account/user.ex == ** (Protocol.UndefinedError) protocol Enumerable not implemented for nil of type Atom (elixir 1.14.4) lib/enum.ex:1: Enumerable.impl_for!/1 (elixir 1.14.4) lib/enum.ex:166: Enumerable.reduce/3 (elixir 1.14.4) lib/enum.ex:436: Enum.any?/2 (pow 1.0.26) lib/pow/ecto/schema.ex:396: Pow.Ecto.Schema.missing_field?/3 (elixir 1.14.4) lib/enum.ex:4197: Enum.filter_list/2 (pow 1.0.26) lib/pow/ecto/schema.ex:375: Pow.Ecto.Schema.__require_fields__/1

I added some log in lib/pow/ecto.schema.ex

  defp missing_field?({name, type}, ecto_fields, _changeset_fields),
    do: missing_field?(name, type, ecto_fields)
  defp missing_field?(name, type, existing_fields) do
    not Enum.any?(existing_fields, fn
      {^name, ^type}  -> true
      {^name, e_type} -> not Type.primitive?(e_type)
      _any            -> false
    end)
  end

then I got these messages bleow...

[updated_at: :utc_datetime_usec, inserted_at: :utc_datetime_usec, address: :string, visit_date: :utc_datetime, name_asterisk: :string, personal_survey: {:array, :integer}, tutorial: :boolean, password_hash: :string, family_id: :id, hospital_code: :integer, birth: :date, grade: :integer, gender: :integer, phonenum_hash: Cloak.Ecto.SHA256, phonenum: HippoAbs.Type.EncryptedBinary, type: :integer, aggrement: {:parameterized, Ecto.Enum, %{embed_as: :self, mappings: [none: "none", required: "required", option: "option", all: "all"], on_cast: %{"all" => :all, "none" => :none, "option" => :option, "required" => :required}, on_dump: %{all: "all", none: "none", option: "option", required: "required"}, on_load: %{"all" => :all, "none" => :none, "option" => :option, "required" => :required}, type: :string}}, email: :string, name: :string, uid: :string, id: :id] :password_hash [updated_at: :utc_datetime_usec, inserted_at: :utc_datetime_usec, address: :string, visit_date: :utc_datetime, name_asterisk: :string, personal_survey: {:array, :integer}, tutorial: :boolean, password_hash: :string, family_id: :id, hospital_code: :integer, birth: :date, grade: :integer, gender: :integer, phonenum_hash: Cloak.Ecto.SHA256, phonenum: HippoAbs.Type.EncryptedBinary, type: :integer, aggrement: {:parameterized, Ecto.Enum, %{embed_as: :self, mappings: [none: "none", required: "required", option: "option", all: "all"], on_cast: %{"all" => :all, "none" => :none, "option" => :option, "required" => :required}, on_dump: %{all: "all", none: "none", option: "option", required: "required"}, on_load: %{"all" => :all, "none" => :none, "option" => :option, "required" => :required}, type: :string}}, email: :string, name: :string, uid: :string, id: :id] :current_password nil

**changeset_fields in Pow.Ecto.Schema is nil. I have no idea when this field is set.

so I got nil so it crashed at missing_field? function.**

alexsysm commented 1 year ago

I found this.

TODO: Require Ecto 3.8.0 in 1.1.0 and remove :changeset_fields

changeset_fields = Module.get_attribute(module, :ecto_changeset_fields) || Module.get_attribute(module, :changeset_fields)