Add password changing

This commit is contained in:
Shadowfacts 2019-03-31 11:52:20 -04:00
parent 4d4c4d3508
commit cf1be80746
Signed by: shadowfacts
GPG Key ID: 94A5AB95422746E5
6 changed files with 105 additions and 4 deletions

View File

@ -29,17 +29,29 @@ defmodule Frenzy.User do
|> 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
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: %{username: username, password: password, fever_password: fever_password}
changes: %{username: username, fever_password: fever_password}
} = changeset
) do
changeset
|> change(Bcrypt.add_hash(password))
|> change(%{
change(changeset, %{
fever_auth_token:
:crypto.hash(:md5, "#{username}:#{fever_password}") |> Base.encode16(case: :lower)
})

View File

@ -0,0 +1,59 @@
defmodule FrenzyWeb.AccountController do
use FrenzyWeb, :controller
alias Frenzy.{Repo, User}
alias FrenzyWeb.Router.Helpers, as: Routes
alias FrenzyWeb.Endpoint
def show(conn, _params) do
user = conn.assigns[:user]
render(conn, "show.html", %{
user: user
})
end
def change_password(conn, _params) do
render(conn, "change_password.html")
end
def do_change_password(conn, %{
"old_password" => old,
"new_password" => new,
"confirm_new_password" => confirm
}) do
user = conn.assigns[:user] |> Repo.preload([:approved_clients, :groups])
case Bcrypt.check_pass(user, old) do
{:ok, user} ->
case new do
^old ->
conn
|> put_flash(:error, "New password cannot be the same as old password.")
|> redirect(to: Routes.account_path(Endpoint, :change_password))
^confirm ->
changeset = User.change_password_changeset(user, %{password: new})
{:ok, user} = Repo.update(changeset)
conn
|> put_flash(:info, "Password changed.")
|> redirect(to: Routes.account_path(Endpoint, :show))
_ ->
conn
|> put_flash(:error, "New password and confirmation did not match.")
|> redirect(to: Routes.account_path(Endpoint, :change_password))
end
{:error, _reason} ->
conn
|> put_flash(:error, "Invalid old password.")
|> redirect(to: Routes.account_path(Endpoint, :change_password))
end
end
def do_change_password(conn, _params) do
redirect(conn, to: Routes.account_path(Endpoint, :change_password))
end
end

View File

@ -35,6 +35,10 @@ defmodule FrenzyWeb.Router do
pipe_through :browser
pipe_through :browser_authenticate
get "/account", AccountController, :show
get "/account/change_password", AccountController, :change_password
post "/account/change_password", AccountController, :do_change_password
get "/", GroupController, :index
resources "/groups", GroupController, except: [:edit, :update]

View File

@ -0,0 +1,19 @@
<h2>Change Password</h2>
<%= form_tag Routes.account_path(@conn, :do_change_password), method: :post do %>
<div class="form-group">
<label for="old_password">Old Password</label>
<input type="password" name="old_password" id="old_password" minlength="8">
</div>
<div class="form-group">
<label for="new_password">New Password</label>
<input type="password" name="new_password" id="new_password" minlength="8">
</div>
<div class="form-group">
<label for="confirm_new_password">Confirm New Password</label>
<input type="password" name="confirm_new_password" id="confirm_new_password" minlength="8">
</div>
<div class="form-group">
<%= submit "Change Password" %>
</div>
<% end %>

View File

@ -0,0 +1,4 @@
<h1>User Settings</h1>
<h2><%= @user.username %></h2>
<a href="<%= Routes.account_path(@conn, :change_password) %>" class="button">Change Password</a>

View File

@ -0,0 +1,3 @@
defmodule FrenzyWeb.AccountView do
use FrenzyWeb, :view
end