Merge branch 'fix/captcha' into 'develop'
Fix account registration when captcha is enabled but not provided Closes #1712 See merge request pleroma/pleroma!2438
This commit is contained in:
commit
2008fa9c7f
11 changed files with 250 additions and 163 deletions
|
|
@ -94,24 +94,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
|
|||
|
||||
@doc "POST /api/v1/accounts"
|
||||
def create(%{assigns: %{app: app}, body_params: params} = conn, _params) do
|
||||
params =
|
||||
params
|
||||
|> Map.take([
|
||||
:email,
|
||||
:bio,
|
||||
:captcha_solution,
|
||||
:captcha_token,
|
||||
:captcha_answer_data,
|
||||
:token,
|
||||
:password,
|
||||
:fullname
|
||||
])
|
||||
|> Map.put(:nickname, params.username)
|
||||
|> Map.put(:fullname, Map.get(params, :fullname, params.username))
|
||||
|> Map.put(:confirm, params.password)
|
||||
|> Map.put(:trusted_app, app.trusted)
|
||||
|
||||
with :ok <- validate_email_param(params),
|
||||
:ok <- TwitterAPI.validate_captcha(app, params),
|
||||
{:ok, user} <- TwitterAPI.register_user(params, need_confirmation: true),
|
||||
{:ok, token} <- Token.create_token(app, user, %{scopes: app.scopes}) do
|
||||
json(conn, %{
|
||||
|
|
@ -121,7 +105,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
|
|||
created_at: Token.Utils.format_created_at(token)
|
||||
})
|
||||
else
|
||||
{:error, errors} -> json_response(conn, :bad_request, errors)
|
||||
{:error, error} -> json_response(conn, :bad_request, %{error: error})
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -133,11 +117,11 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
|
|||
render_error(conn, :forbidden, "Invalid credentials")
|
||||
end
|
||||
|
||||
defp validate_email_param(%{:email => email}) when not is_nil(email), do: :ok
|
||||
defp validate_email_param(%{email: email}) when not is_nil(email), do: :ok
|
||||
|
||||
defp validate_email_param(_) do
|
||||
case Pleroma.Config.get([:instance, :account_activation_required]) do
|
||||
true -> {:error, %{"error" => "Missing parameters"}}
|
||||
true -> {:error, dgettext("errors", "Missing parameter: %{name}", name: "email")}
|
||||
_ -> :ok
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -3,54 +3,27 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
|
||||
import Pleroma.Web.Gettext
|
||||
|
||||
alias Pleroma.Emails.Mailer
|
||||
alias Pleroma.Emails.UserEmail
|
||||
alias Pleroma.Repo
|
||||
alias Pleroma.User
|
||||
alias Pleroma.UserInviteToken
|
||||
|
||||
require Pleroma.Constants
|
||||
|
||||
def register_user(params, opts \\ []) do
|
||||
params =
|
||||
params
|
||||
|> Map.take([
|
||||
:nickname,
|
||||
:password,
|
||||
:captcha_solution,
|
||||
:captcha_token,
|
||||
:captcha_answer_data,
|
||||
:token,
|
||||
:email,
|
||||
:trusted_app
|
||||
])
|
||||
|> Map.put(:bio, User.parse_bio(params[:bio] || ""))
|
||||
|> Map.put(:name, params.fullname)
|
||||
|> Map.put(:password_confirmation, params[:confirm])
|
||||
|> Map.take([:email, :token, :password])
|
||||
|> Map.put(:bio, params |> Map.get(:bio, "") |> User.parse_bio())
|
||||
|> Map.put(:nickname, params[:username])
|
||||
|> Map.put(:name, Map.get(params, :fullname, params[:username]))
|
||||
|> Map.put(:password_confirmation, params[:password])
|
||||
|
||||
case validate_captcha(params) do
|
||||
:ok ->
|
||||
if Pleroma.Config.get([:instance, :registrations_open]) do
|
||||
create_user(params, opts)
|
||||
else
|
||||
create_user_with_invite(params, opts)
|
||||
end
|
||||
|
||||
{:error, error} ->
|
||||
# I have no idea how this error handling works
|
||||
{:error, %{error: Jason.encode!(%{captcha: [error]})}}
|
||||
end
|
||||
end
|
||||
|
||||
defp validate_captcha(params) do
|
||||
if params[:trusted_app] || not Pleroma.Config.get([Pleroma.Captcha, :enabled]) do
|
||||
:ok
|
||||
if Pleroma.Config.get([:instance, :registrations_open]) do
|
||||
create_user(params, opts)
|
||||
else
|
||||
Pleroma.Captcha.validate(
|
||||
params.captcha_token,
|
||||
params.captcha_solution,
|
||||
params.captcha_answer_data
|
||||
)
|
||||
create_user_with_invite(params, opts)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -75,16 +48,17 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
|
|||
|
||||
{:error, changeset} ->
|
||||
errors =
|
||||
Ecto.Changeset.traverse_errors(changeset, fn {msg, _opts} -> msg end)
|
||||
changeset
|
||||
|> Ecto.Changeset.traverse_errors(fn {msg, _opts} -> msg end)
|
||||
|> Jason.encode!()
|
||||
|
||||
{:error, %{error: errors}}
|
||||
{:error, errors}
|
||||
end
|
||||
end
|
||||
|
||||
def password_reset(nickname_or_email) do
|
||||
with true <- is_binary(nickname_or_email),
|
||||
%User{local: true, email: email} = user when not is_nil(email) <-
|
||||
%User{local: true, email: email} = user when is_binary(email) <-
|
||||
User.get_by_nickname_or_email(nickname_or_email),
|
||||
{:ok, token_record} <- Pleroma.PasswordResetToken.create_token(user) do
|
||||
user
|
||||
|
|
@ -106,4 +80,58 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
|
|||
{:error, "unknown user"}
|
||||
end
|
||||
end
|
||||
|
||||
def validate_captcha(app, params) do
|
||||
if app.trusted || not Pleroma.Captcha.enabled?() do
|
||||
:ok
|
||||
else
|
||||
do_validate_captcha(params)
|
||||
end
|
||||
end
|
||||
|
||||
defp do_validate_captcha(params) do
|
||||
with :ok <- validate_captcha_presence(params),
|
||||
:ok <-
|
||||
Pleroma.Captcha.validate(
|
||||
params[:captcha_token],
|
||||
params[:captcha_solution],
|
||||
params[:captcha_answer_data]
|
||||
) do
|
||||
:ok
|
||||
else
|
||||
{:error, :captcha_error} ->
|
||||
captcha_error(dgettext("errors", "CAPTCHA Error"))
|
||||
|
||||
{:error, :invalid} ->
|
||||
captcha_error(dgettext("errors", "Invalid CAPTCHA"))
|
||||
|
||||
{:error, :kocaptcha_service_unavailable} ->
|
||||
captcha_error(dgettext("errors", "Kocaptcha service unavailable"))
|
||||
|
||||
{:error, :expired} ->
|
||||
captcha_error(dgettext("errors", "CAPTCHA expired"))
|
||||
|
||||
{:error, :already_used} ->
|
||||
captcha_error(dgettext("errors", "CAPTCHA already used"))
|
||||
|
||||
{:error, :invalid_answer_data} ->
|
||||
captcha_error(dgettext("errors", "Invalid answer data"))
|
||||
|
||||
{:error, error} ->
|
||||
captcha_error(error)
|
||||
end
|
||||
end
|
||||
|
||||
defp validate_captcha_presence(params) do
|
||||
[:captcha_solution, :captcha_token, :captcha_answer_data]
|
||||
|> Enum.find_value(:ok, fn key ->
|
||||
unless is_binary(params[key]) do
|
||||
error = dgettext("errors", "Invalid CAPTCHA (Missing parameter: %{name})", name: key)
|
||||
{:error, error}
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
# For some reason FE expects error message to be a serialized JSON
|
||||
defp captcha_error(error), do: {:error, Jason.encode!(%{captcha: [error]})}
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue