defmodule Frenzy.User do use Ecto.Schema import Ecto.Changeset schema "users" do field :username, :string field :password, :string, virtual: true field :password_hash, :string field :fever_password, :string, virtual: true field :fever_auth_token, :string has_many :approved_clients, Frenzy.ApprovedClient, on_delete: :delete_all has_many :groups, Frenzy.Group, on_delete: :delete_all timestamps() end @doc false def changeset(user, attrs) do user |> cast(attrs, [:username, :password_hash]) |> validate_required([:username, :password_hash]) end def registration_changeset(user, attrs) do user |> cast(attrs, [:username, :password, :fever_password]) |> validate_length(:password, min: 8) |> validate_length(:fever_password, min: 8) |> put_password_hash() |> put_fever_token() end def change_password_changeset(user, attrs) do user |> cast(attrs, [:password]) |> validate_length(:password, min: 8) |> put_password_hash() end def change_fever_password_changeset(user, attrs) do user |> cast(attrs, [:username, :fever_password]) |> validate_length(:fever_password, min: 8) |> put_fever_token() end defp put_password_hash( %Ecto.Changeset{valid?: true, changes: %{password: password}} = changeset ) do change(changeset, Bcrypt.add_hash(password)) end defp put_fever_token( %Ecto.Changeset{ valid?: true, changes: %{fever_password: fever_password} } = changeset ) do username = Map.get(changeset.changes, "username") || changeset.data.username IO.inspect(username) change(changeset, %{ fever_auth_token: :crypto.hash(:md5, "#{username}:#{fever_password}") |> Base.encode16(case: :lower) }) end end