Refactor password changes to go through Pleroma.Web.Auth so they can be supported by the different auth backends

This commit is contained in:
Mark Felder 2024-10-11 14:27:11 -04:00
parent 3f3f8bc57a
commit 23f78c7573
4 changed files with 45 additions and 13 deletions

View file

@ -10,4 +10,9 @@ defmodule Pleroma.Web.Auth.Authenticator do
@callback handle_error(Plug.Conn.t(), any()) :: any()
@callback auth_template() :: String.t() | nil
@callback oauth_consumer_template() :: String.t() | nil
@callback change_password(Pleroma.User.t(), String.t(), String.t(), String.t()) ::
{:ok, Pleroma.User.t()} | {:error, term()}
@optional_callbacks change_password: 4
end

View file

@ -6,6 +6,7 @@ defmodule Pleroma.Web.Auth.PleromaAuthenticator do
alias Pleroma.Registration
alias Pleroma.Repo
alias Pleroma.User
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.Plugs.AuthenticationPlug
import Pleroma.Web.Auth.Helpers, only: [fetch_credentials: 1, fetch_user: 1]
@ -101,4 +102,23 @@ def handle_error(%Plug.Conn{} = _conn, error) do
def auth_template, do: nil
def oauth_consumer_template, do: nil
@doc "Changes Pleroma.User password in the database"
def change_password(user, password, new_password, new_password) do
case CommonAPI.Utils.confirm_current_password(user, password) do
{:ok, user} ->
with {:ok, _user} <-
User.reset_password(user, %{
password: new_password,
password_confirmation: new_password
}) do
{:ok, user}
end
error ->
error
end
end
def change_password(_, _, _, _), do: {:error, :password_confirmation}
end

View file

@ -39,4 +39,8 @@ def oauth_consumer_template do
implementation().oauth_consumer_template() ||
Pleroma.Config.get([:auth, :oauth_consumer_template], "consumer.html")
end
@impl true
def change_password(user, password, new_password, new_password_confirmation),
do: implementation().change_password(user, password, new_password, new_password_confirmation)
end

View file

@ -13,6 +13,7 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do
alias Pleroma.Healthcheck
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.Auth.WrapperAuthenticator, as: Authenticator
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.Plugs.OAuthScopesPlug
alias Pleroma.Web.WebFinger
@ -195,19 +196,21 @@ def change_password(
%{assigns: %{user: user}, private: %{open_api_spex: %{body_params: body_params}}} = conn,
_
) do
case CommonAPI.Utils.confirm_current_password(user, body_params.password) do
{:ok, user} ->
with {:ok, _user} <-
User.reset_password(user, %{
password: body_params.new_password,
password_confirmation: body_params.new_password_confirmation
}) do
json(conn, %{status: "success"})
else
{:error, changeset} ->
{_, {error, _}} = Enum.at(changeset.errors, 0)
json(conn, %{error: "New password #{error}."})
end
with {:ok, %User{}} <-
Authenticator.change_password(
user,
body_params.password,
body_params.new_password,
body_params.new_password_confirmation
) do
json(conn, %{status: "success"})
else
{:error, %Ecto.Changeset{} = changeset} ->
{_, {error, _}} = Enum.at(changeset.errors, 0)
json(conn, %{error: "New password #{error}."})
{:error, :password_confirmation} ->
json(conn, %{error: "New password does not match confirmation."})
{:error, msg} ->
json(conn, %{error: msg})