aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/pleroma/captcha/error.ex43
-rw-r--r--lib/pleroma/web/api_spec/errors/registration_user_error.ex33
-rw-r--r--lib/pleroma/web/api_spec/operations/account_operation.ex31
-rw-r--r--lib/pleroma/web/api_spec/render_error.ex64
-rw-r--r--lib/pleroma/web/mastodon_api/controllers/account_controller.ex29
-rw-r--r--lib/pleroma/web/twitter_api/twitter_api.ex39
6 files changed, 168 insertions, 71 deletions
diff --git a/lib/pleroma/captcha/error.ex b/lib/pleroma/captcha/error.ex
new file mode 100644
index 000000000..ec77f1336
--- /dev/null
+++ b/lib/pleroma/captcha/error.ex
@@ -0,0 +1,43 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Captcha.Error do
+ import Pleroma.Web.Gettext
+
+ def message(_reason, opts \\ [])
+
+ def message(:missing_field, %{name: name}) do
+ dgettext(
+ "errors",
+ "Invalid CAPTCHA (Missing parameter: %{name})",
+ name: name
+ )
+ end
+
+ def message(:captcha_error, _) do
+ dgettext("errors", "CAPTCHA Error")
+ end
+
+ def message(:invalid, _) do
+ dgettext("errors", "Invalid CAPTCHA")
+ end
+
+ def message(:kocaptcha_service_unavailable, _) do
+ dgettext("errors", "Kocaptcha service unavailable")
+ end
+
+ def message(:expired, _) do
+ dgettext("errors", "CAPTCHA expired")
+ end
+
+ def message(:already_used, _) do
+ dgettext("errors", "CAPTCHA already used")
+ end
+
+ def message(:invalid_answer_data, _) do
+ dgettext("errors", "Invalid answer data")
+ end
+
+ def message(error, _), do: error
+end
diff --git a/lib/pleroma/web/api_spec/errors/registration_user_error.ex b/lib/pleroma/web/api_spec/errors/registration_user_error.ex
new file mode 100644
index 000000000..1e48e12c9
--- /dev/null
+++ b/lib/pleroma/web/api_spec/errors/registration_user_error.ex
@@ -0,0 +1,33 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.ApiSpec.Errors.RegistrationUserError do
+ @behaviour Plug
+
+ import Plug.Conn, only: [put_status: 2]
+ import Phoenix.Controller, only: [json: 2]
+ alias Pleroma.Web.ApiSpec.RenderError
+
+ @impl Plug
+ def init(opts), do: opts
+
+ @impl Plug
+
+ def call(conn, errors) do
+ field_errors =
+ errors
+ |> Enum.group_by(& &1.name)
+ |> Enum.into(%{}, fn {field, field_errors} ->
+ {field, Enum.map(field_errors, &RenderError.message/1)}
+ end)
+
+ conn
+ |> put_status(:bad_request)
+ |> json(%{
+ error: "Please review the submission",
+ identifier: "review_submission",
+ fields: field_errors
+ })
+ end
+end
diff --git a/lib/pleroma/web/api_spec/operations/account_operation.ex b/lib/pleroma/web/api_spec/operations/account_operation.ex
index d90ddb787..d68501bb8 100644
--- a/lib/pleroma/web/api_spec/operations/account_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/account_operation.ex
@@ -34,7 +34,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
requestBody: request_body("Parameters", create_request(), required: true),
responses: %{
200 => Operation.response("Account", "application/json", create_response()),
- 400 => Operation.response("Error", "application/json", ApiError),
+ 400 => Operation.response("Error", "application/json", error_response()),
403 => Operation.response("Error", "application/json", ApiError),
429 => Operation.response("Error", "application/json", ApiError)
}
@@ -453,6 +453,35 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
}
end
+ defp error_response do
+ %Schema{
+ title: "AccountCreateErrorResponse",
+ description: "Response schema for errors",
+ type: :object,
+ properties: %{
+ identifier: %Schema{type: :string},
+ message: %Schema{type: :string},
+ fields: %Schema{
+ type: :object,
+ properties: %{
+ captcha: %Schema{type: :array, items: %Schema{type: :string}},
+ email: %Schema{type: :array, items: %Schema{type: :string}},
+ invite: %Schema{type: :array, items: %Schema{type: :string}},
+ password: %Schema{type: :array, items: %Schema{type: :string}},
+ username: %Schema{type: :array, items: %Schema{type: :string}}
+ }
+ }
+ },
+ example: %{
+ "error" => "Please review the submission",
+ "identifier" => "review_submission",
+ "fields" => %{
+ "captcha" => ["Invalid CAPTCHA"]
+ }
+ }
+ }
+ end
+
# Note: this is a token response (if login succeeds!), but there's no oauth operation file yet.
defp create_response do
%Schema{
diff --git a/lib/pleroma/web/api_spec/render_error.ex b/lib/pleroma/web/api_spec/render_error.ex
index d476b8ef3..59154b39e 100644
--- a/lib/pleroma/web/api_spec/render_error.ex
+++ b/lib/pleroma/web/api_spec/render_error.ex
@@ -47,14 +47,14 @@ defmodule Pleroma.Web.ApiSpec.RenderError do
}
end
- defp message(%{reason: :invalid_schema_type, type: type, name: name}) do
+ def message(%{reason: :invalid_schema_type, type: type, name: name}) do
gettext("%{name} - Invalid schema.type. Got: %{type}.",
name: name,
type: inspect(type)
)
end
- defp message(%{reason: :null_value, name: name} = error) do
+ def message(%{reason: :null_value, name: name} = error) do
case error.type do
nil ->
gettext("%{name} - null value.", name: name)
@@ -67,42 +67,42 @@ defmodule Pleroma.Web.ApiSpec.RenderError do
end
end
- defp message(%{reason: :all_of, meta: %{invalid_schema: invalid_schema}}) do
+ def message(%{reason: :all_of, meta: %{invalid_schema: invalid_schema}}) do
gettext(
"Failed to cast value as %{invalid_schema}. Value must be castable using `allOf` schemas listed.",
invalid_schema: invalid_schema
)
end
- defp message(%{reason: :any_of, meta: %{failed_schemas: failed_schemas}}) do
+ def message(%{reason: :any_of, meta: %{failed_schemas: failed_schemas}}) do
gettext("Failed to cast value using any of: %{failed_schemas}.",
failed_schemas: failed_schemas
)
end
- defp message(%{reason: :one_of, meta: %{failed_schemas: failed_schemas}}) do
+ def message(%{reason: :one_of, meta: %{failed_schemas: failed_schemas}}) do
gettext("Failed to cast value to one of: %{failed_schemas}.", failed_schemas: failed_schemas)
end
- defp message(%{reason: :min_length, length: length, name: name}) do
+ def message(%{reason: :min_length, length: length, name: name}) do
gettext("%{name} - String length is smaller than minLength: %{length}.",
name: name,
length: length
)
end
- defp message(%{reason: :max_length, length: length, name: name}) do
+ def message(%{reason: :max_length, length: length, name: name}) do
gettext("%{name} - String length is larger than maxLength: %{length}.",
name: name,
length: length
)
end
- defp message(%{reason: :unique_items, name: name}) do
+ def message(%{reason: :unique_items, name: name}) do
gettext("%{name} - Array items must be unique.", name: name)
end
- defp message(%{reason: :min_items, length: min, value: array, name: name}) do
+ def message(%{reason: :min_items, length: min, value: array, name: name}) do
gettext("%{name} - Array length %{length} is smaller than minItems: %{min}.",
name: name,
length: length(array),
@@ -110,7 +110,7 @@ defmodule Pleroma.Web.ApiSpec.RenderError do
)
end
- defp message(%{reason: :max_items, length: max, value: array, name: name}) do
+ def message(%{reason: :max_items, length: max, value: array, name: name}) do
gettext("%{name} - Array length %{length} is larger than maxItems: %{}.",
name: name,
length: length(array),
@@ -118,7 +118,7 @@ defmodule Pleroma.Web.ApiSpec.RenderError do
)
end
- defp message(%{reason: :multiple_of, length: multiple, value: count, name: name}) do
+ def message(%{reason: :multiple_of, length: multiple, value: count, name: name}) do
gettext("%{name} - %{count} is not a multiple of %{multiple}.",
name: name,
count: count,
@@ -126,8 +126,8 @@ defmodule Pleroma.Web.ApiSpec.RenderError do
)
end
- defp message(%{reason: :exclusive_max, length: max, value: value, name: name})
- when value >= max do
+ def message(%{reason: :exclusive_max, length: max, value: value, name: name})
+ when value >= max do
gettext("%{name} - %{value} is larger than exclusive maximum %{max}.",
name: name,
value: value,
@@ -135,8 +135,8 @@ defmodule Pleroma.Web.ApiSpec.RenderError do
)
end
- defp message(%{reason: :maximum, length: max, value: value, name: name})
- when value > max do
+ def message(%{reason: :maximum, length: max, value: value, name: name})
+ when value > max do
gettext("%{name} - %{value} is larger than inclusive maximum %{max}.",
name: name,
value: value,
@@ -144,8 +144,8 @@ defmodule Pleroma.Web.ApiSpec.RenderError do
)
end
- defp message(%{reason: :exclusive_multiple, length: min, value: value, name: name})
- when value <= min do
+ def message(%{reason: :exclusive_multiple, length: min, value: value, name: name})
+ when value <= min do
gettext("%{name} - %{value} is smaller than exclusive minimum %{min}.",
name: name,
value: value,
@@ -153,8 +153,8 @@ defmodule Pleroma.Web.ApiSpec.RenderError do
)
end
- defp message(%{reason: :minimum, length: min, value: value, name: name})
- when value < min do
+ def message(%{reason: :minimum, length: min, value: value, name: name})
+ when value < min do
gettext("%{name} - %{value} is smaller than inclusive minimum %{min}.",
name: name,
value: value,
@@ -162,7 +162,7 @@ defmodule Pleroma.Web.ApiSpec.RenderError do
)
end
- defp message(%{reason: :invalid_type, type: type, value: value, name: name}) do
+ def message(%{reason: :invalid_type, type: type, value: value, name: name}) do
gettext("%{name} - Invalid %{type}. Got: %{value}.",
name: name,
value: OpenApiSpex.TermType.type(value),
@@ -170,49 +170,49 @@ defmodule Pleroma.Web.ApiSpec.RenderError do
)
end
- defp message(%{reason: :invalid_format, format: format, name: name}) do
+ def message(%{reason: :invalid_format, format: format, name: name}) do
gettext("%{name} - Invalid format. Expected %{format}.", name: name, format: inspect(format))
end
- defp message(%{reason: :invalid_enum, name: name}) do
+ def message(%{reason: :invalid_enum, name: name}) do
gettext("%{name} - Invalid value for enum.", name: name)
end
- defp message(%{reason: :polymorphic_failed, type: polymorphic_type}) do
+ def message(%{reason: :polymorphic_failed, type: polymorphic_type}) do
gettext("Failed to cast to any schema in %{polymorphic_type}",
polymorphic_type: polymorphic_type
)
end
- defp message(%{reason: :unexpected_field, name: name}) do
+ def message(%{reason: :unexpected_field, name: name}) do
gettext("Unexpected field: %{name}.", name: safe_string(name))
end
- defp message(%{reason: :no_value_for_discriminator, name: field}) do
+ def message(%{reason: :no_value_for_discriminator, name: field}) do
gettext("Value used as discriminator for `%{field}` matches no schemas.", name: field)
end
- defp message(%{reason: :invalid_discriminator_value, name: field}) do
+ def message(%{reason: :invalid_discriminator_value, name: field}) do
gettext("No value provided for required discriminator `%{field}`.", name: field)
end
- defp message(%{reason: :unknown_schema, name: name}) do
+ def message(%{reason: :unknown_schema, name: name}) do
gettext("Unknown schema: %{name}.", name: name)
end
- defp message(%{reason: :missing_field, name: name}) do
+ def message(%{reason: :missing_field, name: name}) do
gettext("Missing field: %{name}.", name: name)
end
- defp message(%{reason: :missing_header, name: name}) do
+ def message(%{reason: :missing_header, name: name}) do
gettext("Missing header: %{name}.", name: name)
end
- defp message(%{reason: :invalid_header, name: name}) do
+ def message(%{reason: :invalid_header, name: name}) do
gettext("Invalid value for header: %{name}.", name: name)
end
- defp message(%{reason: :max_properties, meta: meta}) do
+ def message(%{reason: :max_properties, meta: meta}) do
gettext(
"Object property count %{property_count} is greater than maxProperties: %{max_properties}.",
property_count: meta.property_count,
@@ -220,7 +220,7 @@ defmodule Pleroma.Web.ApiSpec.RenderError do
)
end
- defp message(%{reason: :min_properties, meta: meta}) do
+ def message(%{reason: :min_properties, meta: meta}) do
gettext(
"Object property count %{property_count} is less than minProperties: %{min_properties}",
property_count: meta.property_count,
diff --git a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex
index 4f9696d52..2047e2439 100644
--- a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex
+++ b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex
@@ -19,6 +19,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.Builder
alias Pleroma.Web.ActivityPub.Pipeline
+ alias Pleroma.Web.ApiSpec.Errors.RegistrationUserError
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.MastodonAPI.ListView
alias Pleroma.Web.MastodonAPI.MastodonAPI
@@ -31,7 +32,12 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
alias Pleroma.Web.Plugs.RateLimiter
alias Pleroma.Web.TwitterAPI.TwitterAPI
- plug(Pleroma.Web.ApiSpec.CastAndValidate)
+ plug(
+ Pleroma.Web.ApiSpec.CastAndValidate,
+ [render_error: RegistrationUserError] when action in [:create]
+ )
+
+ plug(Pleroma.Web.ApiSpec.CastAndValidate when action not in [:create])
plug(:skip_plug, [OAuthScopesPlug, EnsurePublicOrAuthenticatedPlug] when action == :create)
@@ -101,8 +107,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
with :ok <- validate_email_param(params),
:ok <- TwitterAPI.validate_captcha(app, params),
{:ok, user} <- TwitterAPI.register_user(params),
- {_, {:ok, token}} <-
- {:login, OAuthController.login(user, app, app.scopes)} do
+ {_, {:ok, token}} <- {:login, OAuthController.login(user, app, app.scopes)} do
json(conn, OAuthView.render("token.json", %{user: user, token: token}))
else
{:login, {:account_status, :confirmation_pending}} ->
@@ -126,8 +131,12 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
identifier: "manual_login_required"
})
- {:error, error} ->
- json_response(conn, :bad_request, %{error: error})
+ {:error, errors} ->
+ json_response(conn, :bad_request, %{
+ identifier: "review_submission",
+ error: "Please review the submission",
+ fields: errors
+ })
end
end
@@ -143,8 +152,14 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
defp validate_email_param(_) do
case Pleroma.Config.get([:instance, :account_activation_required]) do
- true -> {:error, dgettext("errors", "Missing parameter: %{name}", name: "email")}
- _ -> :ok
+ true ->
+ {:error,
+ %{
+ email: [dgettext("errors", "Missing parameter: %{name}", name: "email")]
+ }}
+
+ _ ->
+ :ok
end
end
diff --git a/lib/pleroma/web/twitter_api/twitter_api.ex b/lib/pleroma/web/twitter_api/twitter_api.ex
index 5d7948507..92b071a81 100644
--- a/lib/pleroma/web/twitter_api/twitter_api.ex
+++ b/lib/pleroma/web/twitter_api/twitter_api.ex
@@ -3,14 +3,12 @@
# 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
+ @spec register_user(map(), keyword()) :: {:ok, User.t()} | {:error, map()}
def register_user(params, opts \\ []) do
params =
params
@@ -28,18 +26,20 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
end
end
+ @spec create_user_with_invite(map(), keyword()) :: {:ok, User.t()} | {:error, map()}
defp create_user_with_invite(params, opts) do
with %{token: token} when is_binary(token) <- params,
- %UserInviteToken{} = invite <- Repo.get_by(UserInviteToken, %{token: token}),
+ {:ok, invite} <- UserInviteToken.find_by_token(token),
true <- UserInviteToken.valid_invite?(invite) do
UserInviteToken.update_usage!(invite)
create_user(params, opts)
else
- nil -> {:error, "Invalid token"}
- _ -> {:error, "Expired token"}
+ nil -> {:error, %{invite: ["Invalid token"]}}
+ _ -> {:error, %{invite: ["Expired token"]}}
end
end
+ @spec create_user(map(), keyword()) :: {:ok, User.t()} | {:error, map()}
defp create_user(params, opts) do
changeset = User.register_changeset(%User{}, params, opts)
@@ -52,7 +52,6 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
errors =
changeset
|> Ecto.Changeset.traverse_errors(fn {msg, _opts} -> msg end)
- |> Jason.encode!()
{:error, errors}
end
@@ -104,26 +103,8 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
) 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)
+ {:error, %{captcha: [Pleroma.Captcha.Error.message(error)]}}
end
end
@@ -131,12 +112,8 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI 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}
+ {:error, Pleroma.Captcha.Error.message(:missing_field, %{name: key})}
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