Current section
Files
Jump to
Current section
Files
lib/rit_database/accounts/credential.ex
defmodule RitDatabase.Accounts.Credential do
@moduledoc """
The user main credential entity
Attributes:
- email
- password: Used to receive plain password
- password_confirmation: Used to receive plain password confirmation
- password_hash: The password encrypted
- user
"""
use Ecto.Schema
import Ecto.Changeset
alias Ecto.Changeset
alias RitDatabase.Accounts.{Credential, User}
schema "credentials" do
field :email, :string
field :password, :string, virtual: true
field :password_confirmation, :string, virtual: true
field :password_hash, :string
belongs_to :user, User
timestamps()
end
def changeset(%Credential{} = credential, attrs) do
credential
|> cast(attrs, [:email])
|> validate_required([:email])
end
def create_changeset(%Credential{} = credential, attrs) do
credential
|> cast(attrs, [:email, :password, :password_confirmation])
|> validate_required([:email, :password])
|> validate_email()
|> validate_password()
|> create_password_hash()
end
@email_regex ~r/^.+@.+\..+$/
@email_error "should be a valid password"
defp validate_email(%Changeset{} = changeset) do
changeset
|> validate_length(:email, max: 100)
|> validate_format(:email, @email_regex, message: @email_error)
|> update_change(:email, &String.downcase/1)
|> unique_constraint(:email)
end
@uppercased_regex ~r/[A-Z]+/
@uppercased_error "should contain at least one uppercased letter"
@lowercased_regex ~r/[a-z]+/
@lowercased_error "should contain at least one lowercased letter"
@number_regex ~r/[0-9]+/
@number_error "should contain at least one number"
defp validate_password(%Changeset{} = changeset) do
changeset
|> validate_length(:password, min: 8, max: 50)
|> validate_format(:password, @uppercased_regex, message: @uppercased_error)
|> validate_format(:password, @lowercased_regex, message: @lowercased_error)
|> validate_format(:password, @number_regex, message: @number_error)
end
defp create_password_hash(%Changeset{valid?: true, changes: %{password: password}} = changeset) do
change(changeset, Argon2.add_hash(password))
end
defp create_password_hash(%Changeset{} = changeset) do
changeset
end
end