Skip to content
Snippets Groups Projects
Commit 6af164f2 authored by Roger Braun's avatar Roger Braun
Browse files

Add password reset.

parent a17b2613
No related branches found
No related tags found
No related merge requests found
defmodule Pleroma.PasswordResetToken do
use Ecto.Schema
import Ecto.{Changeset, Query}
alias Pleroma.{User, PasswordResetToken, Repo}
schema "password_reset_tokens" do
belongs_to :user, User
field :token, :string
field :used, :boolean, default: false
timestamps()
end
def create_token(%User{} = user) do
token = :crypto.strong_rand_bytes(32) |> Base.url_encode64
token = %PasswordResetToken{
user_id: user.id,
used: false,
token: token
}
Repo.insert(token)
end
def used_changeset(struct) do
changeset = struct
|> cast(%{}, [])
|> put_change(:used, true)
end
def reset_password(token, data) do
with %{used: false} = token <- Repo.get_by(PasswordResetToken, %{token: token}),
%User{} = user <- Repo.get(User, token.user_id),
{:ok, user} <- User.reset_password(user, data),
{:ok, token} <- Repo.update(used_changeset(token)) do
{:ok, token}
else
_e -> {:error, token}
end
end
end
......@@ -97,6 +97,25 @@ defmodule Pleroma.User do
|> validate_length(:name, min: 1, max: 100)
end
def password_update_changeset(struct, params) do
changeset = struct
|> cast(params, [:password, :password_confirmation])
|> validate_required([:password, :password_confirmation])
|> validate_confirmation(:password)
if changeset.valid? do
hashed = Pbkdf2.hashpwsalt(changeset.changes[:password])
changeset
|> put_change(:password_hash, hashed)
else
changeset
end
end
def reset_password(user, data) do
Repo.update(password_update_changeset(user, data))
end
def register_changeset(struct, params \\ %{}) do
changeset = struct
|> cast(params, [:bio, :email, :name, :nickname, :password, :password_confirmation])
......
......@@ -33,6 +33,16 @@ defmodule Pleroma.Web.Router do
plug :accepts, ["html", "json"]
end
pipeline :password_reset do
plug :accepts, ["html"]
end
scope "/api/pleroma", Pleroma.Web.TwitterAPI do
pipe_through :password_reset
get "/password_reset/:token", UtilController, :show_password_reset
post "/password_reset", UtilController, :password_reset
end
scope "/oauth", Pleroma.Web.OAuth do
get "/authorize", OAuthController, :authorize
post "/authorize", OAuthController, :create_authorization
......
<h2>Invalid Token</h2>
<h2>Password Reset for <%= @user.nickname %></h2>
<%= form_for @conn, util_path(@conn, :password_reset), [as: "data"], fn f -> %>
<%= label f, :password, "Password" %>
<%= password_input f, :password %>
<br>
<%= label f, :password_confirmation, "Confirmation" %>
<%= password_input f, :password_confirmation %>
<br>
<%= hidden_input f, :token, value: @token.token %>
<%= submit "Reset" %>
<% end %>
<h2>Password reset failed</h2>
<h2>Password changed!</h2>
......@@ -2,6 +2,28 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do
use Pleroma.Web, :controller
alias Pleroma.Web
alias Pleroma.{Repo, PasswordResetToken, User}
def show_password_reset(conn, %{"token" => token}) do
with %{used: false} = token <- Repo.get_by(PasswordResetToken, %{token: token}),
%User{} = user <- Repo.get(User, token.user_id) do
render conn, "password_reset.html", %{
token: token,
user: user
}
else
_e -> render conn, "invalid_token.html"
end
end
def password_reset(conn, %{"data" => data}) do
with {:ok, _} <- PasswordResetToken.reset_password(data["token"], data) do
render conn, "password_reset_success.html"
else
_e -> render conn, "password_reset_failed.html"
end
end
def help_test(conn, _params) do
json(conn, "ok")
end
......
defmodule Pleroma.Web.TwitterAPI.UtilView do
use Pleroma.Web, :view
import Phoenix.HTML.Form
end
defmodule Pleroma.Repo.Migrations.CreatePasswordResetTokens do
use Ecto.Migration
def change do
create table(:password_reset_tokens) do
add :token, :string
add :user_id, references(:users)
add :used, :boolean, default: false
timestamps()
end
end
end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment