Add password reset.
This commit is contained in:
parent
a17b261379
commit
6af164f27b
|
@ -0,0 +1,44 @@
|
||||||
|
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 @@ def update_changeset(struct, params \\ %{}) do
|
||||||
|> validate_length(:name, min: 1, max: 100)
|
|> validate_length(:name, min: 1, max: 100)
|
||||||
end
|
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
|
def register_changeset(struct, params \\ %{}) do
|
||||||
changeset = struct
|
changeset = struct
|
||||||
|> cast(params, [:bio, :email, :name, :nickname, :password, :password_confirmation])
|
|> cast(params, [:bio, :email, :name, :nickname, :password, :password_confirmation])
|
||||||
|
|
|
@ -33,6 +33,16 @@ def user_fetcher(username) do
|
||||||
plug :accepts, ["html", "json"]
|
plug :accepts, ["html", "json"]
|
||||||
end
|
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
|
scope "/oauth", Pleroma.Web.OAuth do
|
||||||
get "/authorize", OAuthController, :authorize
|
get "/authorize", OAuthController, :authorize
|
||||||
post "/authorize", OAuthController, :create_authorization
|
post "/authorize", OAuthController, :create_authorization
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
<h2>Invalid Token</h2>
|
|
@ -0,0 +1,12 @@
|
||||||
|
<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 %>
|
|
@ -0,0 +1 @@
|
||||||
|
<h2>Password reset failed</h2>
|
|
@ -0,0 +1 @@
|
||||||
|
<h2>Password changed!</h2>
|
|
@ -2,6 +2,28 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do
|
||||||
use Pleroma.Web, :controller
|
use Pleroma.Web, :controller
|
||||||
alias Pleroma.Web
|
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
|
def help_test(conn, _params) do
|
||||||
json(conn, "ok")
|
json(conn, "ok")
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
defmodule Pleroma.Web.TwitterAPI.UtilView do
|
||||||
|
use Pleroma.Web, :view
|
||||||
|
import Phoenix.HTML.Form
|
||||||
|
end
|
|
@ -0,0 +1,13 @@
|
||||||
|
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
|
Loading…
Reference in New Issue