fix formatting

This commit is contained in:
Jamil Bou Kheir
2020-05-28 18:04:27 -07:00
parent b2f7dbc7d0
commit 72b3434b23
12 changed files with 109 additions and 31 deletions

View File

@@ -6,7 +6,7 @@ defmodule FgHttp.PasswordResets do
import Ecto.Query, warn: false
alias FgHttp.Repo
alias FgHttp.PasswordResets.PasswordReset
alias FgHttp.Users.PasswordReset
@doc """
Returns the list of password_resets.
@@ -21,6 +21,15 @@ defmodule FgHttp.PasswordResets do
Repo.all(PasswordReset)
end
def load_user_from_valid_token!(token) when is_binary(token) do
Repo.get_by!(
PasswordReset,
reset_token: token,
consumed_at: nil,
reset_sent_at: DateTime.utc_now() - PasswordReset.token_validity_secs()
)
end
@doc """
Gets a single password_reset.

View File

@@ -6,7 +6,7 @@ defmodule FgHttp.Sessions do
import Ecto.Query, warn: false
alias FgHttp.Repo
alias FgHttp.{Sessions.Session, Users.User}
alias FgHttp.{Users.Session, Users.User}
@doc """
Returns the list of sessions.

View File

@@ -1,4 +1,4 @@
defmodule FgHttp.PasswordResets.PasswordReset do
defmodule FgHttp.Users.PasswordReset do
@moduledoc """
Schema for PasswordReset
"""
@@ -9,10 +9,13 @@ defmodule FgHttp.PasswordResets.PasswordReset do
alias FgHttp.{Users, Users.User}
@token_num_bytes 8
# 1 day
@token_validity_secs 86_400
schema "password_resets" do
field :reset_sent_at, :utc_datetime
field :reset_token, :string
field :consumed_at, :string
field :user_email, :string, virtual: true
belongs_to :user, User
@@ -42,6 +45,8 @@ defmodule FgHttp.PasswordResets.PasswordReset do
|> validate_required([:reset_token])
end
def token_validity_secs, do: @token_validity_secs
defp load_user_from_email(
%Ecto.Changeset{
valid?: true,

View File

@@ -1,4 +1,4 @@
defmodule FgHttp.Sessions.Session do
defmodule FgHttp.Users.Session do
@moduledoc """
Represents a Session
"""

View File

@@ -6,7 +6,7 @@ defmodule FgHttp.Users.User do
use Ecto.Schema
import Ecto.Changeset
alias FgHttp.{Devices.Device, Sessions.Session}
alias FgHttp.{Devices.Device, Users.Session}
schema "users" do
field :email, :string
@@ -35,7 +35,7 @@ defmodule FgHttp.Users.User do
|> validate_required([:password_hash])
end
# Only password being updated
# Password updated with user logged in
def update_changeset(
user,
%{
@@ -54,6 +54,23 @@ defmodule FgHttp.Users.User do
|> validate_required([:password_hash])
end
# Password updated from token
def update_changeset(
user,
%{
user: %{
password: _password,
password_confirmation: _password_confirmation
}
} = attrs
) do
user
|> cast(attrs, [:email, :password, :password_confirmation])
|> validate_required([:password, :password_confirmation])
|> put_password_hash()
|> validate_required([:password_hash])
end
# Only email being updated
def update_changeset(user, %{user: %{email: _email}} = attrs) do
user

View File

@@ -4,7 +4,7 @@ defmodule FgHttpWeb.PasswordResetController do
"""
use FgHttpWeb, :controller
alias FgHttp.{PasswordResets, PasswordResets.PasswordReset}
alias FgHttp.{PasswordResets, Users.PasswordReset, Users.User}
plug FgHttpWeb.Plugs.RedirectAuthenticated
@@ -15,6 +15,41 @@ defmodule FgHttpWeb.PasswordResetController do
|> render("new.html", changeset: changeset)
end
def edit(conn, %{"token" => token}) when is_binary(token) do
_user = load_user(conn, token)
changeset = PasswordReset.changeset(%PasswordReset{}, %{})
conn
|> render("edit.html", changeset: changeset)
end
def update(conn, %{
"password_reset" =>
%{
"reset_token" => token,
"user" => %{
"password" => _password,
"password_confirmation" => _password_confirmation
}
} = password_reset_params
})
when is_binary(token) do
user = load_user(conn, token)
case PasswordResets.update_password_reset(user, password_reset_params) do
{:ok, _user} ->
conn
|> clear_session()
|> put_flash(:info, "User password updated successfully. Please sign in.")
|> redirect(to: Routes.session_path(conn, :new))
{:error, changeset} ->
conn
|> put_flash(:error, "Error updating User password.")
|> render("edit.html", changeset: changeset)
end
end
def create(conn, %{"password_reset" => %{"user_email" => _} = password_reset_params}) do
case PasswordResets.create_password_reset(password_reset_params) do
{:ok, _password_reset} ->
@@ -29,4 +64,16 @@ defmodule FgHttpWeb.PasswordResetController do
|> render("new.html", changeset: changeset)
end
end
defp load_user(conn, token) do
case PasswordResets.load_user_from_valid_token!(token) do
nil ->
conn
|> put_status(:not_found)
|> halt()
%User{} = user ->
user
end
end
end

View File

@@ -3,7 +3,7 @@ defmodule FgHttpWeb.SessionController do
Implements the CRUD for a Session
"""
alias FgHttp.{Sessions, Sessions.Session}
alias FgHttp.{Sessions, Users.Session}
use FgHttpWeb, :controller
plug FgHttpWeb.Plugs.RedirectAuthenticated when action in [:new]

View File

@@ -1,19 +0,0 @@
<%= form_for @changeset, @action, fn f -> %>
<%= if @changeset.action do %>
<div class="alert alert-danger">
<p>Oops, something went wrong! Please check the errors below.</p>
</div>
<% end %>
<%= label f, :reset_sent_at %>
<%= datetime_select f, :reset_sent_at %>
<%= error_tag f, :reset_sent_at %>
<%= label f, :reset_token %>
<%= text_input f, :reset_token %>
<%= error_tag f, :reset_token %>
<div>
<%= submit "Save" %>
</div>
<% end %>

View File

@@ -1,5 +1,23 @@
<h1>New Password reset</h1>
<h1>Change Password</h1>
<%= render "form.html", Map.put(assigns, :action, Routes.password_reset_path(@conn, :create)) %>
<%= form_for @changeset, Routes.password_reset_path(@conn, :create), fn f -> %>
<%= if @changeset.action do %>
<div class="alert alert-danger">
<p>Oops, something went wrong! Please check the errors below.</p>
</div>
<% end %>
<%= label f, :reset_sent_at %>
<%= datetime_select f, :reset_sent_at %>
<%= error_tag f, :reset_sent_at %>
<%= label f, :reset_token %>
<%= text_input f, :reset_token %>
<%= error_tag f, :reset_token %>
<div>
<%= submit "Save" %>
</div>
<% end %>
<span><%= link "Back", to: Routes.session_path(@conn, :new) %></span>

View File

@@ -12,6 +12,5 @@ defmodule FgHttp.Repo.Migrations.CreateUsers do
end
create unique_index(:users, [:email])
create unique_index(:users, [:reset_token])
end
end

View File

@@ -4,6 +4,7 @@ defmodule FgHttp.Repo.Migrations.CreatePasswordResets do
def change do
create table(:password_resets) do
add :reset_sent_at, :utc_datetime
add :consumed_at, :utc_datetime
add :reset_token, :string, null: false
add :user_id, references(:users, on_delete: :delete_all), null: false
@@ -12,5 +13,6 @@ defmodule FgHttp.Repo.Migrations.CreatePasswordResets do
create unique_index(:password_resets, [:reset_token])
create index(:password_resets, [:user_id])
create index(:password_resets, [:consumed_at])
end
end

View File

@@ -4,7 +4,7 @@ defmodule FgHttp.PasswordResetsTest do
alias FgHttp.{Fixtures, PasswordResets}
describe "password_resets" do
alias FgHttp.PasswordResets.PasswordReset
alias FgHttp.Users.PasswordReset
@valid_attrs %{reset_sent_at: "2010-04-17T14:00:00Z"}
@update_attrs %{reset_sent_at: "2011-05-18T15:01:01Z"}