1
0
Fork 1
mirror of https://akkoma.dev/AkkomaGang/akkoma.git synced 2024-12-25 04:53:06 +00:00

Merge branch '1940-admin-token-oauthless-auth' into 'develop'

[#1940] Reinstated OAuth-less `admin_token` authentication

Closes #1940

See merge request pleroma/pleroma!2760
This commit is contained in:
feld 2020-07-14 16:48:26 +00:00
commit 2909dc873b
21 changed files with 234 additions and 254 deletions

View file

@ -2008,13 +2008,15 @@
label: "Pleroma Admin Token", label: "Pleroma Admin Token",
type: :group, type: :group,
description: description:
"Allows to set a token that can be used to authenticate with the admin api without using an actual user by giving it as the `admin_token` parameter", "Allows setting a token that can be used to authenticate requests with admin privileges without a normal user account token. Append the `admin_token` parameter to requests to utilize it. (Please reconsider using HTTP Basic Auth or OAuth-based authentication if possible)",
children: [ children: [
%{ %{
key: :admin_token, key: :admin_token,
type: :string, type: :string,
description: "Admin token", description: "Admin token",
suggestions: ["We recommend a secure random string or UUID"] suggestions: [
"Please use a high entropy string or UUID"
]
} }
] ]
}, },

View file

@ -814,6 +814,8 @@ or
curl -H "X-Admin-Token: somerandomtoken" "http://localhost:4000/api/pleroma/admin/users/invites" curl -H "X-Admin-Token: somerandomtoken" "http://localhost:4000/api/pleroma/admin/users/invites"
``` ```
Warning: it's discouraged to use this feature because of the associated security risk: static / rarely changed instance-wide token is much weaker compared to email-password pair of a real admin user; consider using HTTP Basic Auth or OAuth-based authentication instead.
### :auth ### :auth
* `Pleroma.Web.Auth.PleromaAuthenticator`: default database authenticator. * `Pleroma.Web.Auth.PleromaAuthenticator`: default database authenticator.

View file

@ -4,6 +4,9 @@
defmodule Pleroma.Plugs.AdminSecretAuthenticationPlug do defmodule Pleroma.Plugs.AdminSecretAuthenticationPlug do
import Plug.Conn import Plug.Conn
alias Pleroma.Plugs.OAuthScopesPlug
alias Pleroma.Plugs.RateLimiter
alias Pleroma.User alias Pleroma.User
def init(options) do def init(options) do
@ -11,7 +14,10 @@ def init(options) do
end end
def secret_token do def secret_token do
Pleroma.Config.get(:admin_token) case Pleroma.Config.get(:admin_token) do
blank when blank in [nil, ""] -> nil
token -> token
end
end end
def call(%{assigns: %{user: %User{}}} = conn, _), do: conn def call(%{assigns: %{user: %User{}}} = conn, _), do: conn
@ -26,9 +32,9 @@ def call(conn, _) do
def authenticate(%{params: %{"admin_token" => admin_token}} = conn) do def authenticate(%{params: %{"admin_token" => admin_token}} = conn) do
if admin_token == secret_token() do if admin_token == secret_token() do
assign(conn, :user, %User{is_admin: true}) assign_admin_user(conn)
else else
conn handle_bad_token(conn)
end end
end end
@ -36,8 +42,19 @@ def authenticate(conn) do
token = secret_token() token = secret_token()
case get_req_header(conn, "x-admin-token") do case get_req_header(conn, "x-admin-token") do
[^token] -> assign(conn, :user, %User{is_admin: true}) blank when blank in [[], [""]] -> conn
_ -> conn [^token] -> assign_admin_user(conn)
_ -> handle_bad_token(conn)
end end
end end
defp assign_admin_user(conn) do
conn
|> assign(:user, %User{is_admin: true})
|> OAuthScopesPlug.skip_plug()
end
defp handle_bad_token(conn) do
RateLimiter.call(conn, name: :authentication)
end
end end

View file

@ -7,37 +7,18 @@ defmodule Pleroma.Plugs.UserIsAdminPlug do
import Plug.Conn import Plug.Conn
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web.OAuth
def init(options) do def init(options) do
options options
end end
def call(%{assigns: %{user: %User{is_admin: true}} = assigns} = conn, _) do def call(%{assigns: %{user: %User{is_admin: true}}} = conn, _) do
token = assigns[:token] conn
cond do
not Pleroma.Config.enforce_oauth_admin_scope_usage?() ->
conn
token && OAuth.Scopes.contains_admin_scopes?(token.scopes) ->
# Note: checking for _any_ admin scope presence, not necessarily fitting requested action.
# Thus, controller must explicitly invoke OAuthScopesPlug to verify scope requirements.
# Admin might opt out of admin scope for some apps to block any admin actions from them.
conn
true ->
fail(conn)
end
end end
def call(conn, _) do def call(conn, _) do
fail(conn)
end
defp fail(conn) do
conn conn
|> render_error(:forbidden, "User is not an admin or OAuth admin scope is not granted.") |> render_error(:forbidden, "User is not an admin.")
|> halt() |> halt()
end end
end end

View file

@ -29,6 +29,10 @@ def request_body(description, schema_ref, opts \\ []) do
} }
end end
def admin_api_params do
[Operation.parameter(:admin_token, :query, :string, "Allows authorization via admin token.")]
end
def pagination_params do def pagination_params do
[ [
Operation.parameter(:max_id, :query, :string, "Return items older than this ID"), Operation.parameter(:max_id, :query, :string, "Return items older than this ID"),

View file

@ -26,6 +26,7 @@ def show_operation do
%Schema{type: :boolean, default: false}, %Schema{type: :boolean, default: false},
"Get only saved in database settings" "Get only saved in database settings"
) )
| admin_api_params()
], ],
security: [%{"oAuth" => ["read"]}], security: [%{"oAuth" => ["read"]}],
responses: %{ responses: %{
@ -41,6 +42,7 @@ def update_operation do
summary: "Update config settings", summary: "Update config settings",
operationId: "AdminAPI.ConfigController.update", operationId: "AdminAPI.ConfigController.update",
security: [%{"oAuth" => ["write"]}], security: [%{"oAuth" => ["write"]}],
parameters: admin_api_params(),
requestBody: requestBody:
request_body("Parameters", %Schema{ request_body("Parameters", %Schema{
type: :object, type: :object,
@ -73,6 +75,7 @@ def descriptions_operation do
summary: "Get JSON with config descriptions.", summary: "Get JSON with config descriptions.",
operationId: "AdminAPI.ConfigController.descriptions", operationId: "AdminAPI.ConfigController.descriptions",
security: [%{"oAuth" => ["read"]}], security: [%{"oAuth" => ["read"]}],
parameters: admin_api_params(),
responses: %{ responses: %{
200 => 200 =>
Operation.response("Config Descriptions", "application/json", %Schema{ Operation.response("Config Descriptions", "application/json", %Schema{

View file

@ -20,6 +20,7 @@ def index_operation do
summary: "Get a list of generated invites", summary: "Get a list of generated invites",
operationId: "AdminAPI.InviteController.index", operationId: "AdminAPI.InviteController.index",
security: [%{"oAuth" => ["read:invites"]}], security: [%{"oAuth" => ["read:invites"]}],
parameters: admin_api_params(),
responses: %{ responses: %{
200 => 200 =>
Operation.response("Invites", "application/json", %Schema{ Operation.response("Invites", "application/json", %Schema{
@ -51,6 +52,7 @@ def create_operation do
summary: "Create an account registration invite token", summary: "Create an account registration invite token",
operationId: "AdminAPI.InviteController.create", operationId: "AdminAPI.InviteController.create",
security: [%{"oAuth" => ["write:invites"]}], security: [%{"oAuth" => ["write:invites"]}],
parameters: admin_api_params(),
requestBody: requestBody:
request_body("Parameters", %Schema{ request_body("Parameters", %Schema{
type: :object, type: :object,
@ -71,6 +73,7 @@ def revoke_operation do
summary: "Revoke invite by token", summary: "Revoke invite by token",
operationId: "AdminAPI.InviteController.revoke", operationId: "AdminAPI.InviteController.revoke",
security: [%{"oAuth" => ["write:invites"]}], security: [%{"oAuth" => ["write:invites"]}],
parameters: admin_api_params(),
requestBody: requestBody:
request_body( request_body(
"Parameters", "Parameters",
@ -97,6 +100,7 @@ def email_operation do
summary: "Sends registration invite via email", summary: "Sends registration invite via email",
operationId: "AdminAPI.InviteController.email", operationId: "AdminAPI.InviteController.email",
security: [%{"oAuth" => ["write:invites"]}], security: [%{"oAuth" => ["write:invites"]}],
parameters: admin_api_params(),
requestBody: requestBody:
request_body( request_body(
"Parameters", "Parameters",

View file

@ -33,6 +33,7 @@ def index_operation do
%Schema{type: :integer, default: 50}, %Schema{type: :integer, default: 50},
"Number of statuses to return" "Number of statuses to return"
) )
| admin_api_params()
], ],
responses: %{ responses: %{
200 => success_response() 200 => success_response()
@ -46,6 +47,7 @@ def delete_operation do
summary: "Remove a banned MediaProxy URL from Cachex", summary: "Remove a banned MediaProxy URL from Cachex",
operationId: "AdminAPI.MediaProxyCacheController.delete", operationId: "AdminAPI.MediaProxyCacheController.delete",
security: [%{"oAuth" => ["write:media_proxy_caches"]}], security: [%{"oAuth" => ["write:media_proxy_caches"]}],
parameters: admin_api_params(),
requestBody: requestBody:
request_body( request_body(
"Parameters", "Parameters",
@ -71,6 +73,7 @@ def purge_operation do
summary: "Purge and optionally ban a MediaProxy URL", summary: "Purge and optionally ban a MediaProxy URL",
operationId: "AdminAPI.MediaProxyCacheController.purge", operationId: "AdminAPI.MediaProxyCacheController.purge",
security: [%{"oAuth" => ["write:media_proxy_caches"]}], security: [%{"oAuth" => ["write:media_proxy_caches"]}],
parameters: admin_api_params(),
requestBody: requestBody:
request_body( request_body(
"Parameters", "Parameters",

View file

@ -36,6 +36,7 @@ def index_operation do
%Schema{type: :integer, default: 50}, %Schema{type: :integer, default: 50},
"Number of apps to return" "Number of apps to return"
) )
| admin_api_params()
], ],
responses: %{ responses: %{
200 => 200 =>
@ -72,6 +73,7 @@ def create_operation do
summary: "Create OAuth App", summary: "Create OAuth App",
operationId: "AdminAPI.OAuthAppController.create", operationId: "AdminAPI.OAuthAppController.create",
requestBody: request_body("Parameters", create_request()), requestBody: request_body("Parameters", create_request()),
parameters: admin_api_params(),
security: [%{"oAuth" => ["write"]}], security: [%{"oAuth" => ["write"]}],
responses: %{ responses: %{
200 => Operation.response("App", "application/json", oauth_app()), 200 => Operation.response("App", "application/json", oauth_app()),
@ -85,7 +87,7 @@ def update_operation do
tags: ["Admin", "oAuth Apps"], tags: ["Admin", "oAuth Apps"],
summary: "Update OAuth App", summary: "Update OAuth App",
operationId: "AdminAPI.OAuthAppController.update", operationId: "AdminAPI.OAuthAppController.update",
parameters: [id_param()], parameters: [id_param() | admin_api_params()],
security: [%{"oAuth" => ["write"]}], security: [%{"oAuth" => ["write"]}],
requestBody: request_body("Parameters", update_request()), requestBody: request_body("Parameters", update_request()),
responses: %{ responses: %{
@ -103,7 +105,7 @@ def delete_operation do
tags: ["Admin", "oAuth Apps"], tags: ["Admin", "oAuth Apps"],
summary: "Delete OAuth App", summary: "Delete OAuth App",
operationId: "AdminAPI.OAuthAppController.delete", operationId: "AdminAPI.OAuthAppController.delete",
parameters: [id_param()], parameters: [id_param() | admin_api_params()],
security: [%{"oAuth" => ["write"]}], security: [%{"oAuth" => ["write"]}],
responses: %{ responses: %{
204 => no_content_response(), 204 => no_content_response(),

View file

@ -19,6 +19,7 @@ def index_operation do
summary: "List Relays", summary: "List Relays",
operationId: "AdminAPI.RelayController.index", operationId: "AdminAPI.RelayController.index",
security: [%{"oAuth" => ["read"]}], security: [%{"oAuth" => ["read"]}],
parameters: admin_api_params(),
responses: %{ responses: %{
200 => 200 =>
Operation.response("Response", "application/json", %Schema{ Operation.response("Response", "application/json", %Schema{
@ -41,6 +42,7 @@ def follow_operation do
summary: "Follow a Relay", summary: "Follow a Relay",
operationId: "AdminAPI.RelayController.follow", operationId: "AdminAPI.RelayController.follow",
security: [%{"oAuth" => ["write:follows"]}], security: [%{"oAuth" => ["write:follows"]}],
parameters: admin_api_params(),
requestBody: requestBody:
request_body("Parameters", %Schema{ request_body("Parameters", %Schema{
type: :object, type: :object,
@ -64,6 +66,7 @@ def unfollow_operation do
summary: "Unfollow a Relay", summary: "Unfollow a Relay",
operationId: "AdminAPI.RelayController.unfollow", operationId: "AdminAPI.RelayController.unfollow",
security: [%{"oAuth" => ["write:follows"]}], security: [%{"oAuth" => ["write:follows"]}],
parameters: admin_api_params(),
requestBody: requestBody:
request_body("Parameters", %Schema{ request_body("Parameters", %Schema{
type: :object, type: :object,

View file

@ -48,6 +48,7 @@ def index_operation do
%Schema{type: :integer, default: 50}, %Schema{type: :integer, default: 50},
"Number number of log entries per page" "Number number of log entries per page"
) )
| admin_api_params()
], ],
responses: %{ responses: %{
200 => 200 =>
@ -71,7 +72,7 @@ def show_operation do
tags: ["Admin", "Reports"], tags: ["Admin", "Reports"],
summary: "Get an individual report", summary: "Get an individual report",
operationId: "AdminAPI.ReportController.show", operationId: "AdminAPI.ReportController.show",
parameters: [id_param()], parameters: [id_param() | admin_api_params()],
security: [%{"oAuth" => ["read:reports"]}], security: [%{"oAuth" => ["read:reports"]}],
responses: %{ responses: %{
200 => Operation.response("Report", "application/json", report()), 200 => Operation.response("Report", "application/json", report()),
@ -86,6 +87,7 @@ def update_operation do
summary: "Change the state of one or multiple reports", summary: "Change the state of one or multiple reports",
operationId: "AdminAPI.ReportController.update", operationId: "AdminAPI.ReportController.update",
security: [%{"oAuth" => ["write:reports"]}], security: [%{"oAuth" => ["write:reports"]}],
parameters: admin_api_params(),
requestBody: request_body("Parameters", update_request(), required: true), requestBody: request_body("Parameters", update_request(), required: true),
responses: %{ responses: %{
204 => no_content_response(), 204 => no_content_response(),
@ -100,7 +102,7 @@ def notes_create_operation do
tags: ["Admin", "Reports"], tags: ["Admin", "Reports"],
summary: "Create report note", summary: "Create report note",
operationId: "AdminAPI.ReportController.notes_create", operationId: "AdminAPI.ReportController.notes_create",
parameters: [id_param()], parameters: [id_param() | admin_api_params()],
requestBody: requestBody:
request_body("Parameters", %Schema{ request_body("Parameters", %Schema{
type: :object, type: :object,
@ -124,6 +126,7 @@ def notes_delete_operation do
parameters: [ parameters: [
Operation.parameter(:report_id, :path, :string, "Report ID"), Operation.parameter(:report_id, :path, :string, "Report ID"),
Operation.parameter(:id, :path, :string, "Note ID") Operation.parameter(:id, :path, :string, "Note ID")
| admin_api_params()
], ],
security: [%{"oAuth" => ["write:reports"]}], security: [%{"oAuth" => ["write:reports"]}],
responses: %{ responses: %{

View file

@ -55,6 +55,7 @@ def index_operation do
%Schema{type: :integer, default: 50}, %Schema{type: :integer, default: 50},
"Number of statuses to return" "Number of statuses to return"
) )
| admin_api_params()
], ],
responses: %{ responses: %{
200 => 200 =>
@ -71,7 +72,7 @@ def show_operation do
tags: ["Admin", "Statuses"], tags: ["Admin", "Statuses"],
summary: "Show Status", summary: "Show Status",
operationId: "AdminAPI.StatusController.show", operationId: "AdminAPI.StatusController.show",
parameters: [id_param()], parameters: [id_param() | admin_api_params()],
security: [%{"oAuth" => ["read:statuses"]}], security: [%{"oAuth" => ["read:statuses"]}],
responses: %{ responses: %{
200 => Operation.response("Status", "application/json", status()), 200 => Operation.response("Status", "application/json", status()),
@ -85,7 +86,7 @@ def update_operation do
tags: ["Admin", "Statuses"], tags: ["Admin", "Statuses"],
summary: "Change the scope of an individual reported status", summary: "Change the scope of an individual reported status",
operationId: "AdminAPI.StatusController.update", operationId: "AdminAPI.StatusController.update",
parameters: [id_param()], parameters: [id_param() | admin_api_params()],
security: [%{"oAuth" => ["write:statuses"]}], security: [%{"oAuth" => ["write:statuses"]}],
requestBody: request_body("Parameters", update_request(), required: true), requestBody: request_body("Parameters", update_request(), required: true),
responses: %{ responses: %{
@ -100,7 +101,7 @@ def delete_operation do
tags: ["Admin", "Statuses"], tags: ["Admin", "Statuses"],
summary: "Delete an individual reported status", summary: "Delete an individual reported status",
operationId: "AdminAPI.StatusController.delete", operationId: "AdminAPI.StatusController.delete",
parameters: [id_param()], parameters: [id_param() | admin_api_params()],
security: [%{"oAuth" => ["write:statuses"]}], security: [%{"oAuth" => ["write:statuses"]}],
responses: %{ responses: %{
200 => empty_object_response(), 200 => empty_object_response(),

View file

@ -90,110 +90,100 @@ msgid "must be equal to %{number}"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:421 #: lib/pleroma/web/common_api/common_api.ex:505
msgid "Account not found" msgid "Account not found"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:249 #: lib/pleroma/web/common_api/common_api.ex:339
msgid "Already voted" msgid "Already voted"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/oauth/oauth_controller.ex:360 #: lib/pleroma/web/oauth/oauth_controller.ex:359
msgid "Bad request" msgid "Bad request"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:425 #: lib/pleroma/web/activity_pub/activity_pub_controller.ex:426
msgid "Can't delete object" msgid "Can't delete object"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/mastodon_api/controllers/status_controller.ex:196 #: lib/pleroma/web/controller_helper.ex:105
msgid "Can't delete this post" #: lib/pleroma/web/controller_helper.ex:111
msgstr ""
#, elixir-format
#: lib/pleroma/web/controller_helper.ex:95
#: lib/pleroma/web/controller_helper.ex:101
msgid "Can't display this activity" msgid "Can't display this activity"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:227 #: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:285
#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:254
msgid "Can't find user" msgid "Can't find user"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/pleroma_api/controllers/account_controller.ex:114 #: lib/pleroma/web/pleroma_api/controllers/account_controller.ex:61
msgid "Can't get favorites" msgid "Can't get favorites"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:437 #: lib/pleroma/web/activity_pub/activity_pub_controller.ex:438
msgid "Can't like object" msgid "Can't like object"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/common_api/utils.ex:556 #: lib/pleroma/web/common_api/utils.ex:563
msgid "Cannot post an empty status without attachments" msgid "Cannot post an empty status without attachments"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/common_api/utils.ex:504 #: lib/pleroma/web/common_api/utils.ex:511
msgid "Comment must be up to %{max_size} characters" msgid "Comment must be up to %{max_size} characters"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/config/config_db.ex:222 #: lib/pleroma/config/config_db.ex:191
msgid "Config with params %{params} not found" msgid "Config with params %{params} not found"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:95 #: lib/pleroma/web/common_api/common_api.ex:181
#: lib/pleroma/web/common_api/common_api.ex:185
msgid "Could not delete" msgid "Could not delete"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:141 #: lib/pleroma/web/common_api/common_api.ex:231
msgid "Could not favorite" msgid "Could not favorite"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:370 #: lib/pleroma/web/common_api/common_api.ex:453
msgid "Could not pin" msgid "Could not pin"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:112 #: lib/pleroma/web/common_api/common_api.ex:278
msgid "Could not repeat"
msgstr ""
#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:188
msgid "Could not unfavorite" msgid "Could not unfavorite"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:380 #: lib/pleroma/web/common_api/common_api.ex:463
msgid "Could not unpin" msgid "Could not unpin"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:126 #: lib/pleroma/web/common_api/common_api.ex:216
msgid "Could not unrepeat" msgid "Could not unrepeat"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:428 #: lib/pleroma/web/common_api/common_api.ex:512
#: lib/pleroma/web/common_api/common_api.ex:437 #: lib/pleroma/web/common_api/common_api.ex:521
msgid "Could not update state" msgid "Could not update state"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex:202 #: lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex:207
msgid "Error." msgid "Error."
msgstr "" msgstr ""
@ -203,8 +193,8 @@ msgid "Invalid CAPTCHA"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:117 #: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:116
#: lib/pleroma/web/oauth/oauth_controller.ex:569 #: lib/pleroma/web/oauth/oauth_controller.ex:568
msgid "Invalid credentials" msgid "Invalid credentials"
msgstr "" msgstr ""
@ -214,22 +204,22 @@ msgid "Invalid credentials."
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:265 #: lib/pleroma/web/common_api/common_api.ex:355
msgid "Invalid indices" msgid "Invalid indices"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/admin_api/admin_api_controller.ex:1147 #: lib/pleroma/web/admin_api/controllers/fallback_controller.ex:29
msgid "Invalid parameters" msgid "Invalid parameters"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/common_api/utils.ex:411 #: lib/pleroma/web/common_api/utils.ex:414
msgid "Invalid password." msgid "Invalid password."
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:187 #: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:220
msgid "Invalid request" msgid "Invalid request"
msgstr "" msgstr ""
@ -239,44 +229,44 @@ msgid "Kocaptcha service unavailable"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:113 #: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:112
msgid "Missing parameters" msgid "Missing parameters"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/common_api/utils.ex:540 #: lib/pleroma/web/common_api/utils.ex:547
msgid "No such conversation" msgid "No such conversation"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/admin_api/admin_api_controller.ex:439 #: lib/pleroma/web/admin_api/controllers/admin_api_controller.ex:388
#: lib/pleroma/web/admin_api/admin_api_controller.ex:465 lib/pleroma/web/admin_api/admin_api_controller.ex:507 #: lib/pleroma/web/admin_api/controllers/admin_api_controller.ex:414 lib/pleroma/web/admin_api/controllers/admin_api_controller.ex:456
msgid "No such permission_group" msgid "No such permission_group"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/plugs/uploaded_media.ex:74 #: lib/pleroma/plugs/uploaded_media.ex:84
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:485 lib/pleroma/web/admin_api/admin_api_controller.ex:1135 #: lib/pleroma/web/activity_pub/activity_pub_controller.ex:486 lib/pleroma/web/admin_api/controllers/fallback_controller.ex:11
#: lib/pleroma/web/feed/user_controller.ex:73 lib/pleroma/web/ostatus/ostatus_controller.ex:143 #: lib/pleroma/web/feed/user_controller.ex:71 lib/pleroma/web/ostatus/ostatus_controller.ex:143
msgid "Not found" msgid "Not found"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:241 #: lib/pleroma/web/common_api/common_api.ex:331
msgid "Poll's author can't vote" msgid "Poll's author can't vote"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/mastodon_api/controllers/fallback_controller.ex:20 #: lib/pleroma/web/mastodon_api/controllers/fallback_controller.ex:20
#: lib/pleroma/web/mastodon_api/controllers/poll_controller.ex:37 lib/pleroma/web/mastodon_api/controllers/poll_controller.ex:49 #: lib/pleroma/web/mastodon_api/controllers/poll_controller.ex:37 lib/pleroma/web/mastodon_api/controllers/poll_controller.ex:49
#: lib/pleroma/web/mastodon_api/controllers/poll_controller.ex:50 lib/pleroma/web/mastodon_api/controllers/status_controller.ex:290 #: lib/pleroma/web/mastodon_api/controllers/poll_controller.ex:50 lib/pleroma/web/mastodon_api/controllers/status_controller.ex:306
#: lib/pleroma/web/mastodon_api/controllers/subscription_controller.ex:71 #: lib/pleroma/web/mastodon_api/controllers/subscription_controller.ex:71
msgid "Record not found" msgid "Record not found"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/admin_api/admin_api_controller.ex:1153 #: lib/pleroma/web/admin_api/controllers/fallback_controller.ex:35
#: lib/pleroma/web/feed/user_controller.ex:79 lib/pleroma/web/mastodon_api/controllers/fallback_controller.ex:32 #: lib/pleroma/web/feed/user_controller.ex:77 lib/pleroma/web/mastodon_api/controllers/fallback_controller.ex:36
#: lib/pleroma/web/ostatus/ostatus_controller.ex:149 #: lib/pleroma/web/ostatus/ostatus_controller.ex:149
msgid "Something went wrong" msgid "Something went wrong"
msgstr "" msgstr ""
@ -287,7 +277,7 @@ msgid "The message visibility must be direct"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/common_api/utils.ex:566 #: lib/pleroma/web/common_api/utils.ex:573
msgid "The status is over the character limit" msgid "The status is over the character limit"
msgstr "" msgstr ""
@ -302,65 +292,65 @@ msgid "Throttled"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:266 #: lib/pleroma/web/common_api/common_api.ex:356
msgid "Too many choices" msgid "Too many choices"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:442 #: lib/pleroma/web/activity_pub/activity_pub_controller.ex:443
msgid "Unhandled activity type" msgid "Unhandled activity type"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/admin_api/admin_api_controller.ex:536 #: lib/pleroma/web/admin_api/controllers/admin_api_controller.ex:485
msgid "You can't revoke your own admin status." msgid "You can't revoke your own admin status."
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/oauth/oauth_controller.ex:218 #: lib/pleroma/web/oauth/oauth_controller.ex:221
#: lib/pleroma/web/oauth/oauth_controller.ex:309 #: lib/pleroma/web/oauth/oauth_controller.ex:308
msgid "Your account is currently disabled" msgid "Your account is currently disabled"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/oauth/oauth_controller.ex:180 #: lib/pleroma/web/oauth/oauth_controller.ex:183
#: lib/pleroma/web/oauth/oauth_controller.ex:332 #: lib/pleroma/web/oauth/oauth_controller.ex:331
msgid "Your login is missing a confirmed e-mail address" msgid "Your login is missing a confirmed e-mail address"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:389 #: lib/pleroma/web/activity_pub/activity_pub_controller.ex:390
msgid "can't read inbox of %{nickname} as %{as_nickname}" msgid "can't read inbox of %{nickname} as %{as_nickname}"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:472 #: lib/pleroma/web/activity_pub/activity_pub_controller.ex:473
msgid "can't update outbox of %{nickname} as %{as_nickname}" msgid "can't update outbox of %{nickname} as %{as_nickname}"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:388 #: lib/pleroma/web/common_api/common_api.ex:471
msgid "conversation is already muted" msgid "conversation is already muted"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:316 #: lib/pleroma/web/activity_pub/activity_pub_controller.ex:314
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:491 #: lib/pleroma/web/activity_pub/activity_pub_controller.ex:492
msgid "error" msgid "error"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/pleroma_api/controllers/mascot_controller.ex:29 #: lib/pleroma/web/pleroma_api/controllers/mascot_controller.ex:32
msgid "mascots can only be images" msgid "mascots can only be images"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:60 #: lib/pleroma/web/activity_pub/activity_pub_controller.ex:62
msgid "not found" msgid "not found"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/oauth/oauth_controller.ex:395 #: lib/pleroma/web/oauth/oauth_controller.ex:394
msgid "Bad OAuth request." msgid "Bad OAuth request."
msgstr "" msgstr ""
@ -375,17 +365,17 @@ msgid "CAPTCHA expired"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/plugs/uploaded_media.ex:55 #: lib/pleroma/plugs/uploaded_media.ex:57
msgid "Failed" msgid "Failed"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/oauth/oauth_controller.ex:411 #: lib/pleroma/web/oauth/oauth_controller.ex:410
msgid "Failed to authenticate: %{message}." msgid "Failed to authenticate: %{message}."
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/oauth/oauth_controller.ex:442 #: lib/pleroma/web/oauth/oauth_controller.ex:441
msgid "Failed to set up user account." msgid "Failed to set up user account."
msgstr "" msgstr ""
@ -395,7 +385,7 @@ msgid "Insufficient permissions: %{permissions}."
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/plugs/uploaded_media.ex:94 #: lib/pleroma/plugs/uploaded_media.ex:104
msgid "Internal Error" msgid "Internal Error"
msgstr "" msgstr ""
@ -411,12 +401,12 @@ msgid "Invalid answer data"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/nodeinfo/nodeinfo_controller.ex:128 #: lib/pleroma/web/nodeinfo/nodeinfo_controller.ex:33
msgid "Nodeinfo schema version not handled" msgid "Nodeinfo schema version not handled"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/oauth/oauth_controller.ex:169 #: lib/pleroma/web/oauth/oauth_controller.ex:172
msgid "This action is outside the authorized scopes" msgid "This action is outside the authorized scopes"
msgstr "" msgstr ""
@ -426,13 +416,13 @@ msgid "Unknown error, please check the details and try again."
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/oauth/oauth_controller.ex:116 #: lib/pleroma/web/oauth/oauth_controller.ex:119
#: lib/pleroma/web/oauth/oauth_controller.ex:155 #: lib/pleroma/web/oauth/oauth_controller.ex:158
msgid "Unlisted redirect_uri." msgid "Unlisted redirect_uri."
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/oauth/oauth_controller.ex:391 #: lib/pleroma/web/oauth/oauth_controller.ex:390
msgid "Unsupported OAuth provider: %{provider}." msgid "Unsupported OAuth provider: %{provider}."
msgstr "" msgstr ""
@ -452,12 +442,12 @@ msgid "CAPTCHA Error"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:200 #: lib/pleroma/web/common_api/common_api.ex:290
msgid "Could not add reaction emoji" msgid "Could not add reaction emoji"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:211 #: lib/pleroma/web/common_api/common_api.ex:301
msgid "Could not remove reaction emoji" msgid "Could not remove reaction emoji"
msgstr "" msgstr ""
@ -472,39 +462,45 @@ msgid "List not found"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:124 #: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:123
msgid "Missing parameter: %{name}" msgid "Missing parameter: %{name}"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/oauth/oauth_controller.ex:207 #: lib/pleroma/web/oauth/oauth_controller.ex:210
#: lib/pleroma/web/oauth/oauth_controller.ex:322 #: lib/pleroma/web/oauth/oauth_controller.ex:321
msgid "Password reset is required" msgid "Password reset is required"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/tests/auth_test_controller.ex:9 #: lib/pleroma/tests/auth_test_controller.ex:9
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:6 lib/pleroma/web/admin_api/admin_api_controller.ex:6 #: lib/pleroma/web/activity_pub/activity_pub_controller.ex:6 lib/pleroma/web/admin_api/controllers/admin_api_controller.ex:6
#: lib/pleroma/web/controller_helper.ex:6 lib/pleroma/web/fallback_redirect_controller.ex:6 #: lib/pleroma/web/admin_api/controllers/config_controller.ex:6 lib/pleroma/web/admin_api/controllers/fallback_controller.ex:6
#: lib/pleroma/web/feed/tag_controller.ex:6 lib/pleroma/web/feed/user_controller.ex:6 #: lib/pleroma/web/admin_api/controllers/invite_controller.ex:6 lib/pleroma/web/admin_api/controllers/media_proxy_cache_controller.ex:6
#: lib/pleroma/web/mailer/subscription_controller.ex:2 lib/pleroma/web/masto_fe_controller.ex:6 #: lib/pleroma/web/admin_api/controllers/oauth_app_controller.ex:6 lib/pleroma/web/admin_api/controllers/relay_controller.ex:6
#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/app_controller.ex:6 #: lib/pleroma/web/admin_api/controllers/report_controller.ex:6 lib/pleroma/web/admin_api/controllers/status_controller.ex:6
#: lib/pleroma/web/mastodon_api/controllers/auth_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/conversation_controller.ex:6 #: lib/pleroma/web/controller_helper.ex:6 lib/pleroma/web/embed_controller.ex:6
#: lib/pleroma/web/mastodon_api/controllers/custom_emoji_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/domain_block_controller.ex:6 #: lib/pleroma/web/fallback_redirect_controller.ex:6 lib/pleroma/web/feed/tag_controller.ex:6
#: lib/pleroma/web/mastodon_api/controllers/fallback_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/filter_controller.ex:6 #: lib/pleroma/web/feed/user_controller.ex:6 lib/pleroma/web/mailer/subscription_controller.ex:2
#: lib/pleroma/web/mastodon_api/controllers/follow_request_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/instance_controller.ex:6 #: lib/pleroma/web/masto_fe_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/account_controller.ex:6
#: lib/pleroma/web/mastodon_api/controllers/list_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/marker_controller.ex:6 #: lib/pleroma/web/mastodon_api/controllers/app_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/auth_controller.ex:6
#: lib/pleroma/web/mastodon_api/controllers/mastodon_api_controller.ex:14 lib/pleroma/web/mastodon_api/controllers/media_controller.ex:6 #: lib/pleroma/web/mastodon_api/controllers/conversation_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/custom_emoji_controller.ex:6
#: lib/pleroma/web/mastodon_api/controllers/notification_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/poll_controller.ex:6 #: lib/pleroma/web/mastodon_api/controllers/domain_block_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/fallback_controller.ex:6
#: lib/pleroma/web/mastodon_api/controllers/report_controller.ex:8 lib/pleroma/web/mastodon_api/controllers/scheduled_activity_controller.ex:6 #: lib/pleroma/web/mastodon_api/controllers/filter_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/follow_request_controller.ex:6
#: lib/pleroma/web/mastodon_api/controllers/search_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/status_controller.ex:6 #: lib/pleroma/web/mastodon_api/controllers/instance_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/list_controller.ex:6
#: lib/pleroma/web/mastodon_api/controllers/subscription_controller.ex:7 lib/pleroma/web/mastodon_api/controllers/suggestion_controller.ex:6 #: lib/pleroma/web/mastodon_api/controllers/marker_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/mastodon_api_controller.ex:14
#: lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex:6 lib/pleroma/web/media_proxy/media_proxy_controller.ex:6 #: lib/pleroma/web/mastodon_api/controllers/media_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/notification_controller.ex:6
#: lib/pleroma/web/mongooseim/mongoose_im_controller.ex:6 lib/pleroma/web/nodeinfo/nodeinfo_controller.ex:6 #: lib/pleroma/web/mastodon_api/controllers/poll_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/report_controller.ex:8
#: lib/pleroma/web/oauth/fallback_controller.ex:6 lib/pleroma/web/oauth/mfa_controller.ex:10 #: lib/pleroma/web/mastodon_api/controllers/scheduled_activity_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/search_controller.ex:6
#: lib/pleroma/web/oauth/oauth_controller.ex:6 lib/pleroma/web/ostatus/ostatus_controller.ex:6 #: lib/pleroma/web/mastodon_api/controllers/status_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/subscription_controller.ex:7
#: lib/pleroma/web/pleroma_api/controllers/account_controller.ex:6 lib/pleroma/web/pleroma_api/controllers/emoji_api_controller.ex:2 #: lib/pleroma/web/mastodon_api/controllers/suggestion_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex:6
#: lib/pleroma/web/pleroma_api/controllers/mascot_controller.ex:6 lib/pleroma/web/pleroma_api/controllers/pleroma_api_controller.ex:6 #: lib/pleroma/web/media_proxy/media_proxy_controller.ex:6 lib/pleroma/web/mongooseim/mongoose_im_controller.ex:6
#: lib/pleroma/web/nodeinfo/nodeinfo_controller.ex:6 lib/pleroma/web/oauth/fallback_controller.ex:6
#: lib/pleroma/web/oauth/mfa_controller.ex:10 lib/pleroma/web/oauth/oauth_controller.ex:6
#: lib/pleroma/web/ostatus/ostatus_controller.ex:6 lib/pleroma/web/pleroma_api/controllers/account_controller.ex:6
#: lib/pleroma/web/pleroma_api/controllers/chat_controller.ex:5 lib/pleroma/web/pleroma_api/controllers/conversation_controller.ex:6
#: lib/pleroma/web/pleroma_api/controllers/emoji_pack_controller.ex:2 lib/pleroma/web/pleroma_api/controllers/emoji_reaction_controller.ex:6
#: lib/pleroma/web/pleroma_api/controllers/mascot_controller.ex:6 lib/pleroma/web/pleroma_api/controllers/notification_controller.ex:6
#: lib/pleroma/web/pleroma_api/controllers/scrobble_controller.ex:6 #: lib/pleroma/web/pleroma_api/controllers/scrobble_controller.ex:6
#: lib/pleroma/web/pleroma_api/controllers/two_factor_authentication_controller.ex:7 lib/pleroma/web/static_fe/static_fe_controller.ex:6 #: lib/pleroma/web/pleroma_api/controllers/two_factor_authentication_controller.ex:7 lib/pleroma/web/static_fe/static_fe_controller.ex:6
#: lib/pleroma/web/twitter_api/controllers/password_controller.ex:10 lib/pleroma/web/twitter_api/controllers/remote_follow_controller.ex:6 #: lib/pleroma/web/twitter_api/controllers/password_controller.ex:10 lib/pleroma/web/twitter_api/controllers/remote_follow_controller.ex:6
@ -519,46 +515,56 @@ msgid "Two-factor authentication enabled, you must use a access token."
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/pleroma_api/controllers/emoji_api_controller.ex:210 #: lib/pleroma/web/pleroma_api/controllers/emoji_pack_controller.ex:210
msgid "Unexpected error occurred while adding file to pack." msgid "Unexpected error occurred while adding file to pack."
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/pleroma_api/controllers/emoji_api_controller.ex:138 #: lib/pleroma/web/pleroma_api/controllers/emoji_pack_controller.ex:138
msgid "Unexpected error occurred while creating pack." msgid "Unexpected error occurred while creating pack."
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/pleroma_api/controllers/emoji_api_controller.ex:278 #: lib/pleroma/web/pleroma_api/controllers/emoji_pack_controller.ex:278
msgid "Unexpected error occurred while removing file from pack." msgid "Unexpected error occurred while removing file from pack."
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/pleroma_api/controllers/emoji_api_controller.ex:250 #: lib/pleroma/web/pleroma_api/controllers/emoji_pack_controller.ex:250
msgid "Unexpected error occurred while updating file in pack." msgid "Unexpected error occurred while updating file in pack."
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/pleroma_api/controllers/emoji_api_controller.ex:179 #: lib/pleroma/web/pleroma_api/controllers/emoji_pack_controller.ex:179
msgid "Unexpected error occurred while updating pack metadata." msgid "Unexpected error occurred while updating pack metadata."
msgstr "" msgstr ""
#, elixir-format
#: lib/pleroma/plugs/user_is_admin_plug.ex:40
msgid "User is not an admin or OAuth admin scope is not granted."
msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/mastodon_api/controllers/subscription_controller.ex:61 #: lib/pleroma/web/mastodon_api/controllers/subscription_controller.ex:61
msgid "Web push subscription is disabled on this Pleroma instance" msgid "Web push subscription is disabled on this Pleroma instance"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/admin_api/admin_api_controller.ex:502 #: lib/pleroma/web/admin_api/controllers/admin_api_controller.ex:451
msgid "You can't revoke your own admin/moderator status." msgid "You can't revoke your own admin/moderator status."
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex:105 #: lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex:126
msgid "authorization required for timeline view" msgid "authorization required for timeline view"
msgstr "" msgstr ""
#, elixir-format
#: lib/pleroma/web/mastodon_api/controllers/fallback_controller.ex:24
msgid "Access denied"
msgstr ""
#, elixir-format
#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:282
msgid "This API requires an authenticated user"
msgstr ""
#, elixir-format
#: lib/pleroma/plugs/user_is_admin_plug.ex:21
msgid "User is not an admin."
msgstr ""

View file

@ -562,11 +562,11 @@ msgstr "Errore inaspettato durante l'aggiornamento del file nel pacchetto."
msgid "Unexpected error occurred while updating pack metadata." msgid "Unexpected error occurred while updating pack metadata."
msgstr "Errore inaspettato durante l'aggiornamento dei metadati del pacchetto." msgstr "Errore inaspettato durante l'aggiornamento dei metadati del pacchetto."
#: lib/pleroma/plugs/user_is_admin_plug.ex:40 #: lib/pleroma/plugs/user_is_admin_plug.ex:21
#, elixir-format #, elixir-format
msgid "User is not an admin or OAuth admin scope is not granted." msgid "User is not an admin."
msgstr "" msgstr ""
"L'utente non è un amministratore o non ha ricevuto questa autorizzazione " "L'utente non è un amministratore."
"OAuth." "OAuth."
#: lib/pleroma/web/mastodon_api/controllers/subscription_controller.ex:61 #: lib/pleroma/web/mastodon_api/controllers/subscription_controller.ex:61

View file

@ -559,9 +559,9 @@ msgstr ""
msgid "Unexpected error occurred while updating pack metadata." msgid "Unexpected error occurred while updating pack metadata."
msgstr "" msgstr ""
#: lib/pleroma/plugs/user_is_admin_plug.ex:40 #: lib/pleroma/plugs/user_is_admin_plug.ex:21
#, elixir-format #, elixir-format
msgid "User is not an admin or OAuth admin scope is not granted." msgid "User is not an admin."
msgstr "" msgstr ""
#: lib/pleroma/web/mastodon_api/controllers/subscription_controller.ex:61 #: lib/pleroma/web/mastodon_api/controllers/subscription_controller.ex:61

View file

@ -566,9 +566,9 @@ msgstr "Nieoczekiwany błąd podczas zmieniania pliku w paczce."
msgid "Unexpected error occurred while updating pack metadata." msgid "Unexpected error occurred while updating pack metadata."
msgstr "Nieoczekiwany błąd podczas zmieniania metadanych paczki." msgstr "Nieoczekiwany błąd podczas zmieniania metadanych paczki."
#: lib/pleroma/plugs/user_is_admin_plug.ex:40 #: lib/pleroma/plugs/user_is_admin_plug.ex:21
#, elixir-format #, elixir-format
msgid "User is not an admin or OAuth admin scope is not granted." msgid "User is not an admin."
msgstr "" msgstr ""
#: lib/pleroma/web/mastodon_api/controllers/subscription_controller.ex:61 #: lib/pleroma/web/mastodon_api/controllers/subscription_controller.ex:61

View file

@ -4,9 +4,14 @@
defmodule Pleroma.Plugs.AdminSecretAuthenticationPlugTest do defmodule Pleroma.Plugs.AdminSecretAuthenticationPlugTest do
use Pleroma.Web.ConnCase, async: true use Pleroma.Web.ConnCase, async: true
import Mock
import Pleroma.Factory import Pleroma.Factory
alias Pleroma.Plugs.AdminSecretAuthenticationPlug alias Pleroma.Plugs.AdminSecretAuthenticationPlug
alias Pleroma.Plugs.OAuthScopesPlug
alias Pleroma.Plugs.PlugHelper
alias Pleroma.Plugs.RateLimiter
test "does nothing if a user is assigned", %{conn: conn} do test "does nothing if a user is assigned", %{conn: conn} do
user = insert(:user) user = insert(:user)
@ -25,6 +30,10 @@ test "does nothing if a user is assigned", %{conn: conn} do
describe "when secret set it assigns an admin user" do describe "when secret set it assigns an admin user" do
setup do: clear_config([:admin_token]) setup do: clear_config([:admin_token])
setup_with_mocks([{RateLimiter, [:passthrough], []}]) do
:ok
end
test "with `admin_token` query parameter", %{conn: conn} do test "with `admin_token` query parameter", %{conn: conn} do
Pleroma.Config.put(:admin_token, "password123") Pleroma.Config.put(:admin_token, "password123")
@ -33,12 +42,14 @@ test "with `admin_token` query parameter", %{conn: conn} do
|> AdminSecretAuthenticationPlug.call(%{}) |> AdminSecretAuthenticationPlug.call(%{})
refute conn.assigns[:user] refute conn.assigns[:user]
assert called(RateLimiter.call(conn, name: :authentication))
conn = conn =
%{conn | params: %{"admin_token" => "password123"}} %{conn | params: %{"admin_token" => "password123"}}
|> AdminSecretAuthenticationPlug.call(%{}) |> AdminSecretAuthenticationPlug.call(%{})
assert conn.assigns[:user].is_admin assert conn.assigns[:user].is_admin
assert PlugHelper.plug_skipped?(conn, OAuthScopesPlug)
end end
test "with `x-admin-token` HTTP header", %{conn: conn} do test "with `x-admin-token` HTTP header", %{conn: conn} do
@ -50,6 +61,7 @@ test "with `x-admin-token` HTTP header", %{conn: conn} do
|> AdminSecretAuthenticationPlug.call(%{}) |> AdminSecretAuthenticationPlug.call(%{})
refute conn.assigns[:user] refute conn.assigns[:user]
assert called(RateLimiter.call(conn, name: :authentication))
conn = conn =
conn conn
@ -57,6 +69,7 @@ test "with `x-admin-token` HTTP header", %{conn: conn} do
|> AdminSecretAuthenticationPlug.call(%{}) |> AdminSecretAuthenticationPlug.call(%{})
assert conn.assigns[:user].is_admin assert conn.assigns[:user].is_admin
assert PlugHelper.plug_skipped?(conn, OAuthScopesPlug)
end end
end end
end end

View file

@ -8,112 +8,30 @@ defmodule Pleroma.Plugs.UserIsAdminPlugTest do
alias Pleroma.Plugs.UserIsAdminPlug alias Pleroma.Plugs.UserIsAdminPlug
import Pleroma.Factory import Pleroma.Factory
describe "unless [:auth, :enforce_oauth_admin_scope_usage]," do test "accepts a user that is an admin" do
setup do: clear_config([:auth, :enforce_oauth_admin_scope_usage], false) user = insert(:user, is_admin: true)
test "accepts a user that is an admin" do conn = assign(build_conn(), :user, user)
user = insert(:user, is_admin: true)
conn = assign(build_conn(), :user, user) ret_conn = UserIsAdminPlug.call(conn, %{})
ret_conn = UserIsAdminPlug.call(conn, %{}) assert conn == ret_conn
assert conn == ret_conn
end
test "denies a user that isn't an admin" do
user = insert(:user)
conn =
build_conn()
|> assign(:user, user)
|> UserIsAdminPlug.call(%{})
assert conn.status == 403
end
test "denies when a user isn't set" do
conn = UserIsAdminPlug.call(build_conn(), %{})
assert conn.status == 403
end
end end
describe "with [:auth, :enforce_oauth_admin_scope_usage]," do test "denies a user that isn't an admin" do
setup do: clear_config([:auth, :enforce_oauth_admin_scope_usage], true) user = insert(:user)
setup do conn =
admin_user = insert(:user, is_admin: true) build_conn()
non_admin_user = insert(:user, is_admin: false) |> assign(:user, user)
blank_user = nil |> UserIsAdminPlug.call(%{})
{:ok, %{users: [admin_user, non_admin_user, blank_user]}} assert conn.status == 403
end end
test "if token has any of admin scopes, accepts a user that is an admin", %{conn: conn} do test "denies when a user isn't set" do
user = insert(:user, is_admin: true) conn = UserIsAdminPlug.call(build_conn(), %{})
token = insert(:oauth_token, user: user, scopes: ["admin:something"])
conn = assert conn.status == 403
conn
|> assign(:user, user)
|> assign(:token, token)
ret_conn = UserIsAdminPlug.call(conn, %{})
assert conn == ret_conn
end
test "if token has any of admin scopes, denies a user that isn't an admin", %{conn: conn} do
user = insert(:user, is_admin: false)
token = insert(:oauth_token, user: user, scopes: ["admin:something"])
conn =
conn
|> assign(:user, user)
|> assign(:token, token)
|> UserIsAdminPlug.call(%{})
assert conn.status == 403
end
test "if token has any of admin scopes, denies when a user isn't set", %{conn: conn} do
token = insert(:oauth_token, scopes: ["admin:something"])
conn =
conn
|> assign(:user, nil)
|> assign(:token, token)
|> UserIsAdminPlug.call(%{})
assert conn.status == 403
end
test "if token lacks admin scopes, denies users regardless of is_admin flag",
%{users: users} do
for user <- users do
token = insert(:oauth_token, user: user)
conn =
build_conn()
|> assign(:user, user)
|> assign(:token, token)
|> UserIsAdminPlug.call(%{})
assert conn.status == 403
end
end
test "if token is missing, denies users regardless of is_admin flag", %{users: users} do
for user <- users do
conn =
build_conn()
|> assign(:user, user)
|> assign(:token, nil)
|> UserIsAdminPlug.call(%{})
assert conn.status == 403
end
end
end end
end end

View file

@ -41,6 +41,16 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
{:ok, %{admin: admin, token: token, conn: conn}} {:ok, %{admin: admin, token: token, conn: conn}}
end end
test "with valid `admin_token` query parameter, skips OAuth scopes check" do
clear_config([:admin_token], "password123")
user = insert(:user)
conn = get(build_conn(), "/api/pleroma/admin/users/#{user.nickname}?admin_token=password123")
assert json_response(conn, 200)
end
describe "with [:auth, :enforce_oauth_admin_scope_usage]," do describe "with [:auth, :enforce_oauth_admin_scope_usage]," do
setup do: clear_config([:auth, :enforce_oauth_admin_scope_usage], true) setup do: clear_config([:auth, :enforce_oauth_admin_scope_usage], true)

View file

@ -152,6 +152,14 @@ test "subkeys with full update right merge", %{conn: conn} do
assert emoji_val[:groups] == [a: 1, b: 2] assert emoji_val[:groups] == [a: 1, b: 2]
assert assets_val[:mascots] == [a: 1, b: 2] assert assets_val[:mascots] == [a: 1, b: 2]
end end
test "with valid `admin_token` query parameter, skips OAuth scopes check" do
clear_config([:admin_token], "password123")
build_conn()
|> get("/api/pleroma/admin/config?admin_token=password123")
|> json_response_and_validate_schema(200)
end
end end
test "POST /api/pleroma/admin/config error", %{conn: conn} do test "POST /api/pleroma/admin/config error", %{conn: conn} do

View file

@ -297,7 +297,7 @@ test "returns 403 when requested by a non-admin" do
|> get("/api/pleroma/admin/reports") |> get("/api/pleroma/admin/reports")
assert json_response(conn, :forbidden) == assert json_response(conn, :forbidden) ==
%{"error" => "User is not an admin or OAuth admin scope is not granted."} %{"error" => "User is not an admin."}
end end
test "returns 403 when requested by anonymous" do test "returns 403 when requested by anonymous" do