add username field, make it main log-in method
This commit is contained in:
		
							parent
							
								
									14aefe45ce
								
							
						
					
					
						commit
						016b0b78bd
					
				| @ -10,36 +10,36 @@ defmodule PokemonCouture.Accounts do | ||||
|   ## Database getters | ||||
| 
 | ||||
|   @doc """ | ||||
|   Gets a user by email. | ||||
|   Gets a user by username. | ||||
| 
 | ||||
|   ## Examples | ||||
| 
 | ||||
|       iex> get_user_by_email("foo@example.com") | ||||
|       iex> get_user_by_username("foo@example.com") | ||||
|       %User{} | ||||
| 
 | ||||
|       iex> get_user_by_email("unknown@example.com") | ||||
|       iex> get_user_by_username("unknown@example.com") | ||||
|       nil | ||||
| 
 | ||||
|   """ | ||||
|   def get_user_by_email(email) when is_binary(email) do | ||||
|     Repo.get_by(User, email: email) | ||||
|   def get_user_by_username(username) when is_binary(username) do | ||||
|     Repo.get_by(User, username: username) | ||||
|   end | ||||
| 
 | ||||
|   @doc """ | ||||
|   Gets a user by email and password. | ||||
|   Gets a user by username and password. | ||||
| 
 | ||||
|   ## Examples | ||||
| 
 | ||||
|       iex> get_user_by_email_and_password("foo@example.com", "correct_password") | ||||
|       iex> get_user_by_username_and_password("foo@example.com", "correct_password") | ||||
|       %User{} | ||||
| 
 | ||||
|       iex> get_user_by_email_and_password("foo@example.com", "invalid_password") | ||||
|       iex> get_user_by_username_and_password("foo@example.com", "invalid_password") | ||||
|       nil | ||||
| 
 | ||||
|   """ | ||||
|   def get_user_by_email_and_password(email, password) | ||||
|       when is_binary(email) and is_binary(password) do | ||||
|     user = Repo.get_by(User, email: email) | ||||
|   def get_user_by_username_and_password(username, password) | ||||
|       when is_binary(username) and is_binary(password) do | ||||
|     user = Repo.get_by(User, username: username) | ||||
|     if User.valid_password?(user, password), do: user | ||||
|   end | ||||
| 
 | ||||
|  | ||||
| @ -4,6 +4,7 @@ defmodule PokemonCouture.Accounts.User do | ||||
| 
 | ||||
|   @derive {Inspect, except: [:password]} | ||||
|   schema "users" do | ||||
|     field :username, :string | ||||
|     field :email, :string | ||||
|     field :password, :string, virtual: true | ||||
|     field :hashed_password, :string | ||||
| @ -32,11 +33,21 @@ defmodule PokemonCouture.Accounts.User do | ||||
|   """ | ||||
|   def registration_changeset(user, attrs, opts \\ []) do | ||||
|     user | ||||
|     |> cast(attrs, [:email, :password]) | ||||
|     |> validate_email() | ||||
|     |> cast(attrs, [:username, :email, :password]) | ||||
|     |> validate_username() | ||||
|     |> validate_password(opts) | ||||
|   end | ||||
| 
 | ||||
|   defp validate_username(changeset) do | ||||
|     changeset | ||||
|     |> validate_required([:username]) | ||||
|     |> validate_format(:username, ~r/^[^\s]+$/, message: "must have no spaces") | ||||
|     |> validate_length(:username, max: 160) | ||||
|     |> validate_length(:username, min: 3) | ||||
|     |> unsafe_validate_unique(:username, PokemonCouture.Repo) | ||||
|     |> unique_constraint(:username) | ||||
|   end | ||||
| 
 | ||||
|   defp validate_email(changeset) do | ||||
|     changeset | ||||
|     |> validate_required([:email]) | ||||
|  | ||||
| @ -7,8 +7,8 @@ defmodule PokemonCoutureWeb.UserConfirmationController do | ||||
|     render(conn, "new.html") | ||||
|   end | ||||
| 
 | ||||
|   def create(conn, %{"user" => %{"email" => email}}) do | ||||
|     if user = Accounts.get_user_by_email(email) do | ||||
|   def create(conn, %{"user" => %{"username" => username}}) do | ||||
|     if user = Accounts.get_user_by_username(username) do | ||||
|       Accounts.deliver_user_confirmation_instructions( | ||||
|         user, | ||||
|         &Routes.user_confirmation_url(conn, :confirm, &1) | ||||
|  | ||||
| @ -9,8 +9,8 @@ defmodule PokemonCoutureWeb.UserResetPasswordController do | ||||
|     render(conn, "new.html") | ||||
|   end | ||||
| 
 | ||||
|   def create(conn, %{"user" => %{"email" => email}}) do | ||||
|     if user = Accounts.get_user_by_email(email) do | ||||
|   def create(conn, %{"user" => %{"username" => username}}) do | ||||
|     if user = Accounts.get_user_by_username(username) do | ||||
|       Accounts.deliver_user_reset_password_instructions( | ||||
|         user, | ||||
|         &Routes.user_reset_password_url(conn, :edit, &1) | ||||
|  | ||||
| @ -9,12 +9,12 @@ defmodule PokemonCoutureWeb.UserSessionController do | ||||
|   end | ||||
| 
 | ||||
|   def create(conn, %{"user" => user_params}) do | ||||
|     %{"email" => email, "password" => password} = user_params | ||||
|     %{"username" => username, "password" => password} = user_params | ||||
| 
 | ||||
|     if user = Accounts.get_user_by_email_and_password(email, password) do | ||||
|     if user = Accounts.get_user_by_username_and_password(username, password) do | ||||
|       UserAuth.log_in_user(conn, user, user_params) | ||||
|     else | ||||
|       render(conn, "new.html", error_message: "Invalid email or password") | ||||
|       render(conn, "new.html", error_message: "Invalid username or password") | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|  | ||||
| @ -7,6 +7,10 @@ | ||||
|     </div> | ||||
|   <% end %> | ||||
| 
 | ||||
|   <%= label f, :username %> | ||||
|   <%= text_input f, :username, required: true %> | ||||
|   <%= error_tag f, :username %> | ||||
| 
 | ||||
|   <%= label f, :email %> | ||||
|   <%= email_input f, :email, required: true %> | ||||
|   <%= error_tag f, :email %> | ||||
|  | ||||
| @ -7,8 +7,8 @@ | ||||
|     </div> | ||||
|   <% end %> | ||||
| 
 | ||||
|   <%= label f, :email %> | ||||
|   <%= email_input f, :email, required: true %> | ||||
|   <%= label f, :username %> | ||||
|   <%= text_input f, :username, required: true %> | ||||
| 
 | ||||
|   <%= label f, :password %> | ||||
|   <%= password_input f, :password, required: true %> | ||||
|  | ||||
| @ -5,6 +5,7 @@ defmodule PokemonCouture.Repo.Migrations.CreateUsersAuthTables do | ||||
|     execute "CREATE EXTENSION IF NOT EXISTS citext", "" | ||||
| 
 | ||||
|     create table(:users) do | ||||
|       add :username, :citext, null: false | ||||
|       add :email, :citext, null: false | ||||
|       add :hashed_password, :string, null: false | ||||
|       add :confirmed_at, :naive_datetime | ||||
| @ -12,6 +13,7 @@ defmodule PokemonCouture.Repo.Migrations.CreateUsersAuthTables do | ||||
|     end | ||||
| 
 | ||||
|     create unique_index(:users, [:email]) | ||||
|     create unique_index(:users, [:username]) | ||||
| 
 | ||||
|     create table(:users_tokens) do | ||||
|       add :user_id, references(:users, on_delete: :delete_all), null: false | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user