aboutsummaryrefslogtreecommitdiff
path: root/lib/pleroma/web
diff options
context:
space:
mode:
Diffstat (limited to 'lib/pleroma/web')
-rw-r--r--lib/pleroma/web/activity_pub/activity_pub.ex153
-rw-r--r--lib/pleroma/web/activity_pub/object_validators/audio_video_validator.ex34
-rw-r--r--lib/pleroma/web/admin_api/controllers/admin_api_controller.ex12
-rw-r--r--lib/pleroma/web/admin_api/controllers/chat_controller.ex4
-rw-r--r--lib/pleroma/web/admin_api/controllers/config_controller.ex4
-rw-r--r--lib/pleroma/web/admin_api/controllers/frontend_controller.ex4
-rw-r--r--lib/pleroma/web/admin_api/controllers/instance_document_controller.ex4
-rw-r--r--lib/pleroma/web/admin_api/controllers/invite_controller.ex4
-rw-r--r--lib/pleroma/web/admin_api/controllers/media_proxy_cache_controller.ex4
-rw-r--r--lib/pleroma/web/admin_api/controllers/o_auth_app_controller.ex2
-rw-r--r--lib/pleroma/web/admin_api/controllers/relay_controller.ex4
-rw-r--r--lib/pleroma/web/admin_api/controllers/report_controller.ex4
-rw-r--r--lib/pleroma/web/admin_api/controllers/status_controller.ex4
-rw-r--r--lib/pleroma/web/admin_api/controllers/user_controller.ex134
-rw-r--r--lib/pleroma/web/admin_api/views/account_view.ex19
-rw-r--r--lib/pleroma/web/api_spec.ex9
-rw-r--r--lib/pleroma/web/api_spec/cast_and_validate.ex31
-rw-r--r--lib/pleroma/web/api_spec/operations/admin/chat_operation.ex6
-rw-r--r--lib/pleroma/web/api_spec/operations/admin/config_operation.ex6
-rw-r--r--lib/pleroma/web/api_spec/operations/admin/frontend_operation.ex4
-rw-r--r--lib/pleroma/web/api_spec/operations/admin/instance_document_operation.ex6
-rw-r--r--lib/pleroma/web/api_spec/operations/admin/invite_operation.ex8
-rw-r--r--lib/pleroma/web/api_spec/operations/admin/media_proxy_cache_operation.ex6
-rw-r--r--lib/pleroma/web/api_spec/operations/admin/o_auth_app_operation.ex8
-rw-r--r--lib/pleroma/web/api_spec/operations/admin/relay_operation.ex6
-rw-r--r--lib/pleroma/web/api_spec/operations/admin/report_operation.ex14
-rw-r--r--lib/pleroma/web/api_spec/operations/admin/status_operation.ex8
-rw-r--r--lib/pleroma/web/api_spec/operations/admin/user_operation.ex389
-rw-r--r--lib/pleroma/web/api_spec/operations/chat_operation.ex24
-rw-r--r--lib/pleroma/web/api_spec/operations/conversation_operation.ex27
-rw-r--r--lib/pleroma/web/api_spec/operations/pleroma_emoji_file_operation.ex12
-rw-r--r--lib/pleroma/web/api_spec/operations/pleroma_emoji_pack_operation.ex24
-rw-r--r--lib/pleroma/web/api_spec/operations/pleroma_report_operation.ex97
-rw-r--r--lib/pleroma/web/api_spec/operations/status_operation.ex2
-rw-r--r--lib/pleroma/web/api_spec/schemas/boolean_like.ex10
-rw-r--r--lib/pleroma/web/api_spec/schemas/chat_message.ex6
-rw-r--r--lib/pleroma/web/api_spec/schemas/scheduled_status.ex6
-rw-r--r--lib/pleroma/web/api_spec/schemas/status.ex5
-rw-r--r--lib/pleroma/web/common_api/activity_draft.ex1
-rw-r--r--lib/pleroma/web/fallback/legacy_pleroma_api_rerouter_plug.ex26
-rw-r--r--lib/pleroma/web/mastodon_api/controllers/app_controller.ex20
-rw-r--r--lib/pleroma/web/mastodon_api/controllers/conversation_controller.ex9
-rw-r--r--lib/pleroma/web/mastodon_api/controllers/instance_controller.ex2
-rw-r--r--lib/pleroma/web/mastodon_api/controllers/status_controller.ex20
-rw-r--r--lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex43
-rw-r--r--lib/pleroma/web/mastodon_api/views/app_view.ex4
-rw-r--r--lib/pleroma/web/mastodon_api/views/scheduled_activity_view.ex3
-rw-r--r--lib/pleroma/web/mastodon_api/views/status_view.ex28
-rw-r--r--lib/pleroma/web/pleroma_api/controllers/backup_controller.ex2
-rw-r--r--lib/pleroma/web/pleroma_api/controllers/chat_controller.ex32
-rw-r--r--lib/pleroma/web/pleroma_api/controllers/emoji_file_controller.ex2
-rw-r--r--lib/pleroma/web/pleroma_api/controllers/emoji_pack_controller.ex2
-rw-r--r--lib/pleroma/web/pleroma_api/controllers/report_controller.ex46
-rw-r--r--lib/pleroma/web/pleroma_api/controllers/user_import_controller.ex2
-rw-r--r--lib/pleroma/web/pleroma_api/views/report_view.ex55
-rw-r--r--lib/pleroma/web/plugs/ensure_authenticated_plug.ex4
-rw-r--r--lib/pleroma/web/plugs/ensure_public_or_authenticated_plug.ex5
-rw-r--r--lib/pleroma/web/plugs/ensure_user_token_assigns_plug.ex5
-rw-r--r--lib/pleroma/web/plugs/frontend_static.ex9
-rw-r--r--lib/pleroma/web/plugs/o_auth_scopes_plug.ex11
-rw-r--r--lib/pleroma/web/router.ex63
61 files changed, 1127 insertions, 371 deletions
diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex
index 5392ce7c9..efbf92c70 100644
--- a/lib/pleroma/web/activity_pub/activity_pub.ex
+++ b/lib/pleroma/web/activity_pub/activity_pub.ex
@@ -10,6 +10,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
alias Pleroma.Conversation
alias Pleroma.Conversation.Participation
alias Pleroma.Filter
+ alias Pleroma.Hashtag
alias Pleroma.Maps
alias Pleroma.Notification
alias Pleroma.Object
@@ -465,6 +466,23 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|> Repo.one()
end
+ defp fetch_paginated_optimized(query, opts, pagination) do
+ # Note: tag-filtering funcs may apply "ORDER BY objects.id DESC",
+ # and extra sorting on "activities.id DESC NULLS LAST" would worse the query plan
+ opts = Map.put(opts, :skip_extra_order, true)
+
+ Pagination.fetch_paginated(query, opts, pagination)
+ end
+
+ def fetch_activities(recipients, opts \\ %{}, pagination \\ :keyset) do
+ list_memberships = Pleroma.List.memberships(opts[:user])
+
+ fetch_activities_query(recipients ++ list_memberships, opts)
+ |> fetch_paginated_optimized(opts, pagination)
+ |> Enum.reverse()
+ |> maybe_update_cc(list_memberships, opts[:user])
+ end
+
@spec fetch_public_or_unlisted_activities(map(), Pagination.type()) :: [Activity.t()]
def fetch_public_or_unlisted_activities(opts \\ %{}, pagination \\ :keyset) do
opts = Map.delete(opts, :user)
@@ -472,7 +490,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
[Constants.as_public()]
|> fetch_activities_query(opts)
|> restrict_unlisted(opts)
- |> Pagination.fetch_paginated(opts, pagination)
+ |> fetch_paginated_optimized(opts, pagination)
end
@spec fetch_public_activities(map(), Pagination.type()) :: [Activity.t()]
@@ -698,8 +716,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
end
defp restrict_embedded_tag_all(query, %{tag_all: [_ | _] = tag_all}) do
- tag_all = Enum.map(tag_all, &String.downcase/1)
-
from(
[_activity, object] in query,
where: fragment("(?)->'tag' \\?& (?)", object.data, ^tag_all)
@@ -717,8 +733,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
end
defp restrict_embedded_tag_any(query, %{tag: [_ | _] = tag_any}) do
- tag_any = Enum.map(tag_any, &String.downcase/1)
-
from(
[_activity, object] in query,
where: fragment("(?)->'tag' \\?| (?)", object.data, ^tag_any)
@@ -736,8 +750,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
end
defp restrict_embedded_tag_reject_any(query, %{tag_reject: [_ | _] = tag_reject}) do
- tag_reject = Enum.map(tag_reject, &String.downcase/1)
-
from(
[_activity, object] in query,
where: fragment("not (?)->'tag' \\?| (?)", object.data, ^tag_reject)
@@ -751,6 +763,14 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
defp restrict_embedded_tag_reject_any(query, _), do: query
+ defp object_ids_query_for_tags(tags) do
+ from(hto in "hashtags_objects")
+ |> join(:inner, [hto], ht in Pleroma.Hashtag, on: hto.hashtag_id == ht.id)
+ |> where([hto, ht], ht.name in ^tags)
+ |> select([hto], hto.object_id)
+ |> distinct([hto], true)
+ end
+
defp restrict_hashtag_all(_query, %{tag_all: _tag, skip_preload: true}) do
raise_on_missing_preload()
end
@@ -766,7 +786,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
fragment(
"""
(SELECT array_agg(hashtags.name) FROM hashtags JOIN hashtags_objects
- ON hashtags_objects.hashtag_id = hashtags.id WHERE hashtags.name = ANY(?::citext[])
+ ON hashtags_objects.hashtag_id = hashtags.id WHERE hashtags.name = ANY(?)
AND hashtags_objects.object_id = ?) @> ?
""",
^tags,
@@ -787,42 +807,19 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
end
defp restrict_hashtag_any(query, %{tag: [_ | _] = tags}) do
- # TODO: refactor: debug / experimental feature
- if Config.get([:database, :improved_hashtag_timeline]) == :preselect_hashtag_ids do
- hashtag_ids =
- from(ht in Pleroma.Hashtag,
- where: fragment("name = ANY(?::citext[])", ^tags),
- select: ht.id
- )
- |> Repo.all()
+ hashtag_ids =
+ from(ht in Hashtag, where: ht.name in ^tags, select: ht.id)
+ |> Repo.all()
- from(
- [_activity, object] in query,
- where:
- fragment(
- """
- EXISTS (
- SELECT 1 FROM hashtags_objects WHERE hashtag_id = ANY(?) AND object_id = ? LIMIT 1)
- """,
- ^hashtag_ids,
- object.id
- )
- )
- else
- from(
- [_activity, object] in query,
- where:
- fragment(
- """
- EXISTS (SELECT 1 FROM hashtags JOIN hashtags_objects
- ON hashtags_objects.hashtag_id = hashtags.id WHERE hashtags.name = ANY(?::citext[])
- AND hashtags_objects.object_id = ? LIMIT 1)
- """,
- ^tags,
- object.id
- )
- )
- end
+ # Note: NO extra ordering should be done on "activities.id desc nulls last" for optimal plan
+ from(
+ [_activity, object] in query,
+ join: hto in "hashtags_objects",
+ on: hto.object_id == object.id,
+ where: hto.hashtag_id in ^hashtag_ids,
+ distinct: [desc: object.id],
+ order_by: [desc: object.id]
+ )
end
defp restrict_hashtag_any(query, %{tag: tag}) when is_binary(tag) do
@@ -838,16 +835,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
defp restrict_hashtag_reject_any(query, %{tag_reject: [_ | _] = tags_reject}) do
from(
[_activity, object] in query,
- where:
- fragment(
- """
- NOT EXISTS (SELECT 1 FROM hashtags JOIN hashtags_objects
- ON hashtags_objects.hashtag_id = hashtags.id WHERE hashtags.name = ANY(?::citext[])
- AND hashtags_objects.object_id = ? LIMIT 1)
- """,
- ^tags_reject,
- object.id
- )
+ where: object.id not in subquery(object_ids_query_for_tags(tags_reject))
)
end
@@ -1220,6 +1208,26 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
defp maybe_order(query, _), do: query
+ defp normalize_fetch_activities_query_opts(opts) do
+ Enum.reduce([:tag, :tag_all, :tag_reject], opts, fn key, opts ->
+ case opts[key] do
+ value when is_bitstring(value) ->
+ Map.put(opts, key, Hashtag.normalize_name(value))
+
+ value when is_list(value) ->
+ normalized_value =
+ value
+ |> Enum.map(&Hashtag.normalize_name/1)
+ |> Enum.uniq()
+
+ Map.put(opts, key, normalized_value)
+
+ _ ->
+ opts
+ end
+ end)
+ end
+
defp fetch_activities_query_ap_ids_ops(opts) do
source_user = opts[:muting_user]
ap_id_relationships = if source_user, do: [:mute, :reblog_mute], else: []
@@ -1243,6 +1251,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
end
def fetch_activities_query(recipients, opts \\ %{}) do
+ opts = normalize_fetch_activities_query_opts(opts)
+
{restrict_blocked_opts, restrict_muted_opts, restrict_muted_reblogs_opts} =
fetch_activities_query_ap_ids_ops(opts)
@@ -1284,7 +1294,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|> exclude_invisible_actors(opts)
|> exclude_visibility(opts)
- if Config.get([:database, :improved_hashtag_timeline]) do
+ if Config.feature_enabled?(:improved_hashtag_timeline) do
query
|> restrict_hashtag_any(opts)
|> restrict_hashtag_all(opts)
@@ -1297,15 +1307,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
end
end
- def fetch_activities(recipients, opts \\ %{}, pagination \\ :keyset) do
- list_memberships = Pleroma.List.memberships(opts[:user])
-
- fetch_activities_query(recipients ++ list_memberships, opts)
- |> Pagination.fetch_paginated(opts, pagination)
- |> Enum.reverse()
- |> maybe_update_cc(list_memberships, opts[:user])
- end
-
@doc """
Fetch favorites activities of user with order by sort adds to favorites
"""
@@ -1382,21 +1383,17 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
defp get_actor_url(_url), do: nil
- defp object_to_user_data(data) do
- avatar =
- data["icon"]["url"] &&
- %{
- "type" => "Image",
- "url" => [%{"href" => data["icon"]["url"]}]
- }
+ defp normalize_image(%{"url" => url}) do
+ %{
+ "type" => "Image",
+ "url" => [%{"href" => url}]
+ }
+ end
- banner =
- data["image"]["url"] &&
- %{
- "type" => "Image",
- "url" => [%{"href" => data["image"]["url"]}]
- }
+ defp normalize_image(urls) when is_list(urls), do: urls |> List.first() |> normalize_image()
+ defp normalize_image(_), do: nil
+ defp object_to_user_data(data) do
fields =
data
|> Map.get("attachment", [])
@@ -1440,13 +1437,13 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
ap_id: data["id"],
uri: get_actor_url(data["url"]),
ap_enabled: true,
- banner: banner,
+ banner: normalize_image(data["image"]),
fields: fields,
emoji: emojis,
is_locked: is_locked,
is_discoverable: is_discoverable,
invisible: invisible,
- avatar: avatar,
+ avatar: normalize_image(data["icon"]),
name: data["name"],
follower_address: data["followers"],
following_address: data["following"],
diff --git a/lib/pleroma/web/activity_pub/object_validators/audio_video_validator.ex b/lib/pleroma/web/activity_pub/object_validators/audio_video_validator.ex
index b3e738d8d..4a96fef52 100644
--- a/lib/pleroma/web/activity_pub/object_validators/audio_video_validator.ex
+++ b/lib/pleroma/web/activity_pub/object_validators/audio_video_validator.ex
@@ -70,19 +70,33 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AudioVideoValidator do
|> changeset(data)
end
- defp fix_url(%{"url" => url} = data) when is_list(url) do
- attachment =
- Enum.find(url, fn x ->
- mime_type = x["mimeType"] || x["mediaType"] || ""
-
- is_map(x) and String.starts_with?(mime_type, ["video/", "audio/"])
+ defp find_attachment(url) do
+ mpeg_url =
+ Enum.find(url, fn
+ %{"mediaType" => mime_type, "tag" => tags} when is_list(tags) ->
+ mime_type == "application/x-mpegURL"
+
+ _ ->
+ false
end)
- link_element =
- Enum.find(url, fn x ->
- mime_type = x["mimeType"] || x["mediaType"] || ""
+ url
+ |> Enum.concat(mpeg_url["tag"] || [])
+ |> Enum.find(fn
+ %{"mediaType" => mime_type} -> String.starts_with?(mime_type, ["video/", "audio/"])
+ %{"mimeType" => mime_type} -> String.starts_with?(mime_type, ["video/", "audio/"])
+ _ -> false
+ end)
+ end
- is_map(x) and mime_type == "text/html"
+ defp fix_url(%{"url" => url} = data) when is_list(url) do
+ attachment = find_attachment(url)
+
+ link_element =
+ Enum.find(url, fn
+ %{"mediaType" => "text/html"} -> true
+ %{"mimeType" => "text/html"} -> true
+ _ -> false
end)
data
diff --git a/lib/pleroma/web/admin_api/controllers/admin_api_controller.ex b/lib/pleroma/web/admin_api/controllers/admin_api_controller.ex
index d581df4a2..839ac1a8d 100644
--- a/lib/pleroma/web/admin_api/controllers/admin_api_controller.ex
+++ b/lib/pleroma/web/admin_api/controllers/admin_api_controller.ex
@@ -25,13 +25,13 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
plug(
OAuthScopesPlug,
- %{scopes: ["read:accounts"], admin: true}
+ %{scopes: ["admin:read:accounts"]}
when action in [:right_get, :show_user_credentials, :create_backup]
)
plug(
OAuthScopesPlug,
- %{scopes: ["write:accounts"], admin: true}
+ %{scopes: ["admin:write:accounts"]}
when action in [
:get_password_reset,
:force_password_reset,
@@ -48,19 +48,19 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
plug(
OAuthScopesPlug,
- %{scopes: ["read:statuses"], admin: true}
+ %{scopes: ["admin:read:statuses"]}
when action in [:list_user_statuses, :list_instance_statuses]
)
plug(
OAuthScopesPlug,
- %{scopes: ["read:chats"], admin: true}
+ %{scopes: ["admin:read:chats"]}
when action in [:list_user_chats]
)
plug(
OAuthScopesPlug,
- %{scopes: ["read"], admin: true}
+ %{scopes: ["admin:read"]}
when action in [
:list_log,
:stats,
@@ -70,7 +70,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
plug(
OAuthScopesPlug,
- %{scopes: ["write"], admin: true}
+ %{scopes: ["admin:write"]}
when action in [
:restart,
:resend_confirmation_email,
diff --git a/lib/pleroma/web/admin_api/controllers/chat_controller.ex b/lib/pleroma/web/admin_api/controllers/chat_controller.ex
index 3761a588a..ff20c8604 100644
--- a/lib/pleroma/web/admin_api/controllers/chat_controller.ex
+++ b/lib/pleroma/web/admin_api/controllers/chat_controller.ex
@@ -21,12 +21,12 @@ defmodule Pleroma.Web.AdminAPI.ChatController do
plug(
OAuthScopesPlug,
- %{scopes: ["read:chats"], admin: true} when action in [:show, :messages]
+ %{scopes: ["admin:read:chats"]} when action in [:show, :messages]
)
plug(
OAuthScopesPlug,
- %{scopes: ["write:chats"], admin: true} when action in [:delete_message]
+ %{scopes: ["admin:write:chats"]} when action in [:delete_message]
)
action_fallback(Pleroma.Web.AdminAPI.FallbackController)
diff --git a/lib/pleroma/web/admin_api/controllers/config_controller.ex b/lib/pleroma/web/admin_api/controllers/config_controller.ex
index 4ebf2a305..a718d7b8d 100644
--- a/lib/pleroma/web/admin_api/controllers/config_controller.ex
+++ b/lib/pleroma/web/admin_api/controllers/config_controller.ex
@@ -10,11 +10,11 @@ defmodule Pleroma.Web.AdminAPI.ConfigController do
alias Pleroma.Web.Plugs.OAuthScopesPlug
plug(Pleroma.Web.ApiSpec.CastAndValidate)
- plug(OAuthScopesPlug, %{scopes: ["write"], admin: true} when action == :update)
+ plug(OAuthScopesPlug, %{scopes: ["admin:write"]} when action == :update)
plug(
OAuthScopesPlug,
- %{scopes: ["read"], admin: true}
+ %{scopes: ["admin:read"]}
when action in [:show, :descriptions]
)
diff --git a/lib/pleroma/web/admin_api/controllers/frontend_controller.ex b/lib/pleroma/web/admin_api/controllers/frontend_controller.ex
index 20472a55e..722f51bd2 100644
--- a/lib/pleroma/web/admin_api/controllers/frontend_controller.ex
+++ b/lib/pleroma/web/admin_api/controllers/frontend_controller.ex
@@ -9,8 +9,8 @@ defmodule Pleroma.Web.AdminAPI.FrontendController do
alias Pleroma.Web.Plugs.OAuthScopesPlug
plug(Pleroma.Web.ApiSpec.CastAndValidate)
- plug(OAuthScopesPlug, %{scopes: ["write"], admin: true} when action == :install)
- plug(OAuthScopesPlug, %{scopes: ["read"], admin: true} when action == :index)
+ plug(OAuthScopesPlug, %{scopes: ["admin:write"]} when action == :install)
+ plug(OAuthScopesPlug, %{scopes: ["admin:read"]} when action == :index)
action_fallback(Pleroma.Web.AdminAPI.FallbackController)
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.Admin.FrontendOperation
diff --git a/lib/pleroma/web/admin_api/controllers/instance_document_controller.ex b/lib/pleroma/web/admin_api/controllers/instance_document_controller.ex
index ef00d3417..a55857a0e 100644
--- a/lib/pleroma/web/admin_api/controllers/instance_document_controller.ex
+++ b/lib/pleroma/web/admin_api/controllers/instance_document_controller.ex
@@ -15,8 +15,8 @@ defmodule Pleroma.Web.AdminAPI.InstanceDocumentController do
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.Admin.InstanceDocumentOperation
- plug(OAuthScopesPlug, %{scopes: ["read"], admin: true} when action == :show)
- plug(OAuthScopesPlug, %{scopes: ["write"], admin: true} when action in [:update, :delete])
+ plug(OAuthScopesPlug, %{scopes: ["admin:read"]} when action == :show)
+ plug(OAuthScopesPlug, %{scopes: ["admin:write"]} when action in [:update, :delete])
def show(conn, %{name: document_name}) do
with {:ok, url} <- InstanceDocument.get(document_name),
diff --git a/lib/pleroma/web/admin_api/controllers/invite_controller.ex b/lib/pleroma/web/admin_api/controllers/invite_controller.ex
index 3f233a0c4..727ebd846 100644
--- a/lib/pleroma/web/admin_api/controllers/invite_controller.ex
+++ b/lib/pleroma/web/admin_api/controllers/invite_controller.ex
@@ -14,11 +14,11 @@ defmodule Pleroma.Web.AdminAPI.InviteController do
require Logger
plug(Pleroma.Web.ApiSpec.CastAndValidate)
- plug(OAuthScopesPlug, %{scopes: ["read:invites"], admin: true} when action == :index)
+ plug(OAuthScopesPlug, %{scopes: ["admin:read:invites"]} when action == :index)
plug(
OAuthScopesPlug,
- %{scopes: ["write:invites"], admin: true} when action in [:create, :revoke, :email]
+ %{scopes: ["admin:write:invites"]} when action in [:create, :revoke, :email]
)
action_fallback(Pleroma.Web.AdminAPI.FallbackController)
diff --git a/lib/pleroma/web/admin_api/controllers/media_proxy_cache_controller.ex b/lib/pleroma/web/admin_api/controllers/media_proxy_cache_controller.ex
index 3564738af..a6d7aaf54 100644
--- a/lib/pleroma/web/admin_api/controllers/media_proxy_cache_controller.ex
+++ b/lib/pleroma/web/admin_api/controllers/media_proxy_cache_controller.ex
@@ -15,12 +15,12 @@ defmodule Pleroma.Web.AdminAPI.MediaProxyCacheController do
plug(
OAuthScopesPlug,
- %{scopes: ["read:media_proxy_caches"], admin: true} when action in [:index]
+ %{scopes: ["admin:read:media_proxy_caches"]} when action in [:index]
)
plug(
OAuthScopesPlug,
- %{scopes: ["write:media_proxy_caches"], admin: true} when action in [:purge, :delete]
+ %{scopes: ["admin:write:media_proxy_caches"]} when action in [:purge, :delete]
)
action_fallback(Pleroma.Web.AdminAPI.FallbackController)
diff --git a/lib/pleroma/web/admin_api/controllers/o_auth_app_controller.ex b/lib/pleroma/web/admin_api/controllers/o_auth_app_controller.ex
index 2bd2b3644..005fe67e2 100644
--- a/lib/pleroma/web/admin_api/controllers/o_auth_app_controller.ex
+++ b/lib/pleroma/web/admin_api/controllers/o_auth_app_controller.ex
@@ -17,7 +17,7 @@ defmodule Pleroma.Web.AdminAPI.OAuthAppController do
plug(
OAuthScopesPlug,
- %{scopes: ["write"], admin: true}
+ %{scopes: ["admin:write"]}
when action in [:create, :index, :update, :delete]
)
diff --git a/lib/pleroma/web/admin_api/controllers/relay_controller.ex b/lib/pleroma/web/admin_api/controllers/relay_controller.ex
index 18443e74e..c6bd43fea 100644
--- a/lib/pleroma/web/admin_api/controllers/relay_controller.ex
+++ b/lib/pleroma/web/admin_api/controllers/relay_controller.ex
@@ -15,11 +15,11 @@ defmodule Pleroma.Web.AdminAPI.RelayController do
plug(
OAuthScopesPlug,
- %{scopes: ["write:follows"], admin: true}
+ %{scopes: ["admin:write:follows"]}
when action in [:follow, :unfollow]
)
- plug(OAuthScopesPlug, %{scopes: ["read"], admin: true} when action == :index)
+ plug(OAuthScopesPlug, %{scopes: ["admin:read"]} when action == :index)
action_fallback(Pleroma.Web.AdminAPI.FallbackController)
diff --git a/lib/pleroma/web/admin_api/controllers/report_controller.ex b/lib/pleroma/web/admin_api/controllers/report_controller.ex
index abc068a3f..d4a4935ee 100644
--- a/lib/pleroma/web/admin_api/controllers/report_controller.ex
+++ b/lib/pleroma/web/admin_api/controllers/report_controller.ex
@@ -19,11 +19,11 @@ defmodule Pleroma.Web.AdminAPI.ReportController do
require Logger
plug(Pleroma.Web.ApiSpec.CastAndValidate)
- plug(OAuthScopesPlug, %{scopes: ["read:reports"], admin: true} when action in [:index, :show])
+ plug(OAuthScopesPlug, %{scopes: ["admin:read:reports"]} when action in [:index, :show])
plug(
OAuthScopesPlug,
- %{scopes: ["write:reports"], admin: true}
+ %{scopes: ["admin:write:reports"]}
when action in [:update, :notes_create, :notes_delete]
)
diff --git a/lib/pleroma/web/admin_api/controllers/status_controller.ex b/lib/pleroma/web/admin_api/controllers/status_controller.ex
index 903badec0..7058def82 100644
--- a/lib/pleroma/web/admin_api/controllers/status_controller.ex
+++ b/lib/pleroma/web/admin_api/controllers/status_controller.ex
@@ -15,11 +15,11 @@ defmodule Pleroma.Web.AdminAPI.StatusController do
require Logger
plug(Pleroma.Web.ApiSpec.CastAndValidate)
- plug(OAuthScopesPlug, %{scopes: ["read:statuses"], admin: true} when action in [:index, :show])
+ plug(OAuthScopesPlug, %{scopes: ["admin:read:statuses"]} when action in [:index, :show])
plug(
OAuthScopesPlug,
- %{scopes: ["write:statuses"], admin: true} when action in [:update, :delete]
+ %{scopes: ["admin:write:statuses"]} when action in [:update, :delete]
)
action_fallback(Pleroma.Web.AdminAPI.FallbackController)
diff --git a/lib/pleroma/web/admin_api/controllers/user_controller.ex b/lib/pleroma/web/admin_api/controllers/user_controller.ex
index a18b9f8d5..d3e4c18a3 100644
--- a/lib/pleroma/web/admin_api/controllers/user_controller.ex
+++ b/lib/pleroma/web/admin_api/controllers/user_controller.ex
@@ -13,21 +13,22 @@ defmodule Pleroma.Web.AdminAPI.UserController do
alias Pleroma.Web.ActivityPub.Builder
alias Pleroma.Web.ActivityPub.Pipeline
alias Pleroma.Web.AdminAPI
- alias Pleroma.Web.AdminAPI.AccountView
alias Pleroma.Web.AdminAPI.Search
alias Pleroma.Web.Plugs.OAuthScopesPlug
@users_page_size 50
+ plug(Pleroma.Web.ApiSpec.CastAndValidate)
+
plug(
OAuthScopesPlug,
- %{scopes: ["read:accounts"], admin: true}
- when action in [:list, :show]
+ %{scopes: ["admin:read:accounts"]}
+ when action in [:index, :show]
)
plug(
OAuthScopesPlug,
- %{scopes: ["write:accounts"], admin: true}
+ %{scopes: ["admin:write:accounts"]}
when action in [
:delete,
:create,
@@ -40,17 +41,23 @@ defmodule Pleroma.Web.AdminAPI.UserController do
plug(
OAuthScopesPlug,
- %{scopes: ["write:follows"], admin: true}
+ %{scopes: ["admin:write:follows"]}
when action in [:follow, :unfollow]
)
+ plug(:put_view, Pleroma.Web.AdminAPI.AccountView)
+
action_fallback(AdminAPI.FallbackController)
- def delete(conn, %{"nickname" => nickname}) do
- delete(conn, %{"nicknames" => [nickname]})
+ defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.Admin.UserOperation
+
+ def delete(conn, %{nickname: nickname}) do
+ conn
+ |> Map.put(:body_params, %{nicknames: [nickname]})
+ |> delete(%{})
end
- def delete(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
+ def delete(%{assigns: %{user: admin}, body_params: %{nicknames: nicknames}} = conn, _) do
users = Enum.map(nicknames, &User.get_cached_by_nickname/1)
Enum.each(users, fn user ->
@@ -67,10 +74,16 @@ defmodule Pleroma.Web.AdminAPI.UserController do
json(conn, nicknames)
end
- def follow(%{assigns: %{user: admin}} = conn, %{
- "follower" => follower_nick,
- "followed" => followed_nick
- }) do
+ def follow(
+ %{
+ assigns: %{user: admin},
+ body_params: %{
+ follower: follower_nick,
+ followed: followed_nick
+ }
+ } = conn,
+ _
+ ) do
with %User{} = follower <- User.get_cached_by_nickname(follower_nick),
%User{} = followed <- User.get_cached_by_nickname(followed_nick) do
User.follow(follower, followed)
@@ -86,10 +99,16 @@ defmodule Pleroma.Web.AdminAPI.UserController do
json(conn, "ok")
end
- def unfollow(%{assigns: %{user: admin}} = conn, %{
- "follower" => follower_nick,
- "followed" => followed_nick
- }) do
+ def unfollow(
+ %{
+ assigns: %{user: admin},
+ body_params: %{
+ follower: follower_nick,
+ followed: followed_nick
+ }
+ } = conn,
+ _
+ ) do
with %User{} = follower <- User.get_cached_by_nickname(follower_nick),
%User{} = followed <- User.get_cached_by_nickname(followed_nick) do
User.unfollow(follower, followed)
@@ -105,9 +124,10 @@ defmodule Pleroma.Web.AdminAPI.UserController do
json(conn, "ok")
end
- def create(%{assigns: %{user: admin}} = conn, %{"users" => users}) do
+ def create(%{assigns: %{user: admin}, body_params: %{users: users}} = conn, _) do
changesets =
- Enum.map(users, fn %{"nickname" => nickname, "email" => email, "password" => password} ->
+ users
+ |> Enum.map(fn %{nickname: nickname, email: email, password: password} ->
user_data = %{
nickname: nickname,
name: nickname,
@@ -124,52 +144,49 @@ defmodule Pleroma.Web.AdminAPI.UserController do
end)
case Pleroma.Repo.transaction(changesets) do
- {:ok, users} ->
- res =
- users
+ {:ok, users_map} ->
+ users =
+ users_map
|> Map.values()
|> Enum.map(fn user ->
{:ok, user} = User.post_register_action(user)
user
end)
- |> Enum.map(&AccountView.render("created.json", %{user: &1}))
ModerationLog.insert_log(%{
actor: admin,
- subjects: Map.values(users),
+ subjects: users,
action: "create"
})
- json(conn, res)
+ render(conn, "created_many.json", users: users)
{:error, id, changeset, _} ->
- res =
+ changesets =
Enum.map(changesets.operations, fn
- {current_id, {:changeset, _current_changeset, _}} when current_id == id ->
- AccountView.render("create-error.json", %{changeset: changeset})
+ {^id, {:changeset, _current_changeset, _}} ->
+ changeset
{_, {:changeset, current_changeset, _}} ->
- AccountView.render("create-error.json", %{changeset: current_changeset})
+ current_changeset
end)
conn
|> put_status(:conflict)
- |> json(res)
+ |> render("create_errors.json", changesets: changesets)
end
end
- def show(%{assigns: %{user: admin}} = conn, %{"nickname" => nickname}) do
+ def show(%{assigns: %{user: admin}} = conn, %{nickname: nickname}) do
with %User{} = user <- User.get_cached_by_nickname_or_id(nickname, for: admin) do
- conn
- |> put_view(AccountView)
- |> render("show.json", %{user: user})
+ render(conn, "show.json", %{user: user})
else
_ -> {:error, :not_found}
end
end
- def toggle_activation(%{assigns: %{user: admin}} = conn, %{"nickname" => nickname}) do
+ def toggle_activation(%{assigns: %{user: admin}} = conn, %{nickname: nickname}) do
user = User.get_cached_by_nickname(nickname)
{:ok, updated_user} = User.set_activation(user, !user.is_active)
@@ -182,12 +199,10 @@ defmodule Pleroma.Web.AdminAPI.UserController do
action: action
})
- conn
- |> put_view(AccountView)
- |> render("show.json", %{user: updated_user})
+ render(conn, "show.json", user: updated_user)
end
- def activate(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
+ def activate(%{assigns: %{user: admin}, body_params: %{nicknames: nicknames}} = conn, _) do
users = Enum.map(nicknames, &User.get_cached_by_nickname/1)
{:ok, updated_users} = User.set_activation(users, true)
@@ -197,12 +212,10 @@ defmodule Pleroma.Web.AdminAPI.UserController do
action: "activate"
})
- conn
- |> put_view(AccountView)
- |> render("index.json", %{users: Keyword.values(updated_users)})
+ render(conn, "index.json", users: Keyword.values(updated_users))
end
- def deactivate(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
+ def deactivate(%{assigns: %{user: admin}, body_params: %{nicknames: nicknames}} = conn, _) do
users = Enum.map(nicknames, &User.get_cached_by_nickname/1)
{:ok, updated_users} = User.set_activation(users, false)
@@ -212,12 +225,10 @@ defmodule Pleroma.Web.AdminAPI.UserController do
action: "deactivate"
})
- conn
- |> put_view(AccountView)
- |> render("index.json", %{users: Keyword.values(updated_users)})
+ render(conn, "index.json", users: Keyword.values(updated_users))
end
- def approve(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
+ def approve(%{assigns: %{user: admin}, body_params: %{nicknames: nicknames}} = conn, _) do
users = Enum.map(nicknames, &User.get_cached_by_nickname/1)
{:ok, updated_users} = User.approve(users)
@@ -227,36 +238,27 @@ defmodule Pleroma.Web.AdminAPI.UserController do
action: "approve"
})
- conn
- |> put_view(AccountView)
- |> render("index.json", %{users: updated_users})
+ render(conn, "index.json", users: updated_users)
end
- def list(conn, params) do
+ def index(conn, params) do
{page, page_size} = page_params(params)
- filters = maybe_parse_filters(params["filters"])
+ filters = maybe_parse_filters(params[:filters])
search_params =
%{
- query: params["query"],
+ query: params[:query],
page: page,
page_size: page_size,
- tags: params["tags"],
- name: params["name"],
- email: params["email"],
- actor_types: params["actor_types"]
+ tags: params[:tags],
+ name: params[:name],
+ email: params[:email],
+ actor_types: params[:actor_types]
}
|> Map.merge(filters)
with {:ok, users, count} <- Search.user(search_params) do
- json(
- conn,
- AccountView.render("index.json",
- users: users,
- count: count,
- page_size: page_size
- )
- )
+ render(conn, "index.json", users: users, count: count, page_size: page_size)
end
end
@@ -274,8 +276,8 @@ defmodule Pleroma.Web.AdminAPI.UserController do
defp page_params(params) do
{
- fetch_integer_param(params, "page", 1),
- fetch_integer_param(params, "page_size", @users_page_size)
+ fetch_integer_param(params, :page, 1),
+ fetch_integer_param(params, :page_size, @users_page_size)
}
end
end
diff --git a/lib/pleroma/web/admin_api/views/account_view.ex b/lib/pleroma/web/admin_api/views/account_view.ex
index d7c63d385..e053a9b67 100644
--- a/lib/pleroma/web/admin_api/views/account_view.ex
+++ b/lib/pleroma/web/admin_api/views/account_view.ex
@@ -75,7 +75,7 @@ defmodule Pleroma.Web.AdminAPI.AccountView do
"display_name" => display_name,
"is_active" => user.is_active,
"local" => user.local,
- "roles" => User.roles(user),
+ "roles" => roles(user),
"tags" => user.tags || [],
"is_confirmed" => user.is_confirmed,
"is_approved" => user.is_approved,
@@ -85,6 +85,10 @@ defmodule Pleroma.Web.AdminAPI.AccountView do
}
end
+ def render("created_many.json", %{users: users}) do
+ render_many(users, AccountView, "created.json", as: :user)
+ end
+
def render("created.json", %{user: user}) do
%{
type: "success",
@@ -96,7 +100,11 @@ defmodule Pleroma.Web.AdminAPI.AccountView do
}
end
- def render("create-error.json", %{changeset: %Ecto.Changeset{changes: changes, errors: errors}}) do
+ def render("create_errors.json", %{changesets: changesets}) do
+ render_many(changesets, AccountView, "create_error.json", as: :changeset)
+ end
+
+ def render("create_error.json", %{changeset: %Ecto.Changeset{changes: changes, errors: errors}}) do
%{
type: "error",
code: 409,
@@ -140,4 +148,11 @@ defmodule Pleroma.Web.AdminAPI.AccountView do
defp image_url(%{"url" => [%{"href" => href} | _]}), do: href
defp image_url(_), do: nil
+
+ defp roles(%{is_moderator: is_moderator, is_admin: is_admin}) do
+ %{
+ admin: is_admin,
+ moderator: is_moderator
+ }
+ end
end
diff --git a/lib/pleroma/web/api_spec.ex b/lib/pleroma/web/api_spec.ex
index b16068f7b..528cd9cf4 100644
--- a/lib/pleroma/web/api_spec.ex
+++ b/lib/pleroma/web/api_spec.ex
@@ -85,16 +85,17 @@ defmodule Pleroma.Web.ApiSpec do
"name" => "Administration",
"tags" => [
"Chat administration",
- "Emoji packs",
+ "Emoji pack administration",
"Frontend managment",
"Instance configuration",
"Instance documents",
"Invites",
"MediaProxy cache",
"OAuth application managment",
- "Report managment",
"Relays",
- "Status administration"
+ "Report managment",
+ "Status administration",
+ "User administration"
]
},
%{"name" => "Applications", "tags" => ["Applications", "Push subscriptions"]},
@@ -127,7 +128,7 @@ defmodule Pleroma.Web.ApiSpec do
"Status actions"
]
},
- %{"name" => "Miscellaneous", "tags" => ["Reports", "Suggestions"]}
+ %{"name" => "Miscellaneous", "tags" => ["Emoji packs", "Reports", "Suggestions"]}
]
}
}
diff --git a/lib/pleroma/web/api_spec/cast_and_validate.ex b/lib/pleroma/web/api_spec/cast_and_validate.ex
index a3da856ff..d23a7dcb6 100644
--- a/lib/pleroma/web/api_spec/cast_and_validate.ex
+++ b/lib/pleroma/web/api_spec/cast_and_validate.ex
@@ -15,6 +15,7 @@ defmodule Pleroma.Web.ApiSpec.CastAndValidate do
@behaviour Plug
+ alias OpenApiSpex.Plug.PutApiSpec
alias Plug.Conn
@impl Plug
@@ -25,12 +26,10 @@ defmodule Pleroma.Web.ApiSpec.CastAndValidate do
end
@impl Plug
- def call(%{private: %{open_api_spex: private_data}} = conn, %{
- operation_id: operation_id,
- render_error: render_error
- }) do
- spec = private_data.spec
- operation = private_data.operation_lookup[operation_id]
+
+ def call(conn, %{operation_id: operation_id, render_error: render_error}) do
+ {spec, operation_lookup} = PutApiSpec.get_spec_and_operation_lookup(conn)
+ operation = operation_lookup[operation_id]
content_type =
case Conn.get_req_header(conn, "content-type") do
@@ -43,8 +42,7 @@ defmodule Pleroma.Web.ApiSpec.CastAndValidate do
"application/json"
end
- private_data = Map.put(private_data, :operation_id, operation_id)
- conn = Conn.put_private(conn, :open_api_spex, private_data)
+ conn = Conn.put_private(conn, :operation_id, operation_id)
case cast_and_validate(spec, operation, conn, content_type, strict?()) do
{:ok, conn} ->
@@ -64,25 +62,22 @@ defmodule Pleroma.Web.ApiSpec.CastAndValidate do
private: %{
phoenix_controller: controller,
phoenix_action: action,
- open_api_spex: private_data
+ open_api_spex: %{spec_module: spec_module}
}
} = conn,
opts
) do
+ {spec, operation_lookup} = PutApiSpec.get_spec_and_operation_lookup(conn)
+
operation =
- case private_data.operation_lookup[{controller, action}] do
+ case operation_lookup[{controller, action}] do
nil ->
operation_id = controller.open_api_operation(action).operationId
- operation = private_data.operation_lookup[operation_id]
+ operation = operation_lookup[operation_id]
- operation_lookup =
- private_data.operation_lookup
- |> Map.put({controller, action}, operation)
+ operation_lookup = Map.put(operation_lookup, {controller, action}, operation)
- OpenApiSpex.Plug.Cache.adapter().put(
- private_data.spec_module,
- {private_data.spec, operation_lookup}
- )
+ OpenApiSpex.Plug.Cache.adapter().put(spec_module, {spec, operation_lookup})
operation
diff --git a/lib/pleroma/web/api_spec/operations/admin/chat_operation.ex b/lib/pleroma/web/api_spec/operations/admin/chat_operation.ex
index cbe4b8972..57906445e 100644
--- a/lib/pleroma/web/api_spec/operations/admin/chat_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/admin/chat_operation.ex
@@ -33,7 +33,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.ChatOperation do
},
security: [
%{
- "oAuth" => ["write:chats"]
+ "oAuth" => ["admin:write:chats"]
}
]
}
@@ -57,7 +57,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.ChatOperation do
},
security: [
%{
- "oAuth" => ["read:chats"]
+ "oAuth" => ["admin:read:chats"]
}
]
}
@@ -88,7 +88,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.ChatOperation do
},
security: [
%{
- "oAuth" => ["read"]
+ "oAuth" => ["admin:read"]
}
]
}
diff --git a/lib/pleroma/web/api_spec/operations/admin/config_operation.ex b/lib/pleroma/web/api_spec/operations/admin/config_operation.ex
index b8ccc1d00..30c3433b7 100644
--- a/lib/pleroma/web/api_spec/operations/admin/config_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/admin/config_operation.ex
@@ -28,7 +28,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.ConfigOperation do
)
| admin_api_params()
],
- security: [%{"oAuth" => ["read"]}],
+ security: [%{"oAuth" => ["admin:read"]}],
responses: %{
200 => Operation.response("Config", "application/json", config_response()),
400 => Operation.response("Bad Request", "application/json", ApiError)
@@ -41,7 +41,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.ConfigOperation do
tags: ["Instance configuration"],
summary: "Update instance configuration",
operationId: "AdminAPI.ConfigController.update",
- security: [%{"oAuth" => ["write"]}],
+ security: [%{"oAuth" => ["admin:write"]}],
parameters: admin_api_params(),
requestBody:
request_body("Parameters", %Schema{
@@ -74,7 +74,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.ConfigOperation do
tags: ["Instance configuration"],
summary: "Retrieve config description",
operationId: "AdminAPI.ConfigController.descriptions",
- security: [%{"oAuth" => ["read"]}],
+ security: [%{"oAuth" => ["admin:read"]}],
parameters: admin_api_params(),
responses: %{
200 =>
diff --git a/lib/pleroma/web/api_spec/operations/admin/frontend_operation.ex b/lib/pleroma/web/api_spec/operations/admin/frontend_operation.ex
index b149becf9..566f1eeb1 100644
--- a/lib/pleroma/web/api_spec/operations/admin/frontend_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/admin/frontend_operation.ex
@@ -19,7 +19,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.FrontendOperation do
tags: ["Frontend managment"],
summary: "Retrieve a list of available frontends",
operationId: "AdminAPI.FrontendController.index",
- security: [%{"oAuth" => ["read"]}],
+ security: [%{"oAuth" => ["admin:read"]}],
responses: %{
200 => Operation.response("Response", "application/json", list_of_frontends()),
403 => Operation.response("Forbidden", "application/json", ApiError)
@@ -32,7 +32,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.FrontendOperation do
tags: ["Frontend managment"],
summary: "Install a frontend",
operationId: "AdminAPI.FrontendController.install",
- security: [%{"oAuth" => ["read"]}],
+ security: [%{"oAuth" => ["admin:read"]}],
requestBody: request_body("Parameters", install_request(), required: true),
responses: %{
200 => Operation.response("Response", "application/json", list_of_frontends()),
diff --git a/lib/pleroma/web/api_spec/operations/admin/instance_document_operation.ex b/lib/pleroma/web/api_spec/operations/admin/instance_document_operation.ex
index 3e89abfb5..79ceae970 100644
--- a/lib/pleroma/web/api_spec/operations/admin/instance_document_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/admin/instance_document_operation.ex
@@ -18,7 +18,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.InstanceDocumentOperation do
tags: ["Instance documents"],
summary: "Retrieve an instance document",
operationId: "AdminAPI.InstanceDocumentController.show",
- security: [%{"oAuth" => ["read"]}],
+ security: [%{"oAuth" => ["admin:read"]}],
parameters: [
Operation.parameter(:name, :path, %Schema{type: :string}, "The document name",
required: true
@@ -39,7 +39,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.InstanceDocumentOperation do
tags: ["Instance documents"],
summary: "Update an instance document",
operationId: "AdminAPI.InstanceDocumentController.update",
- security: [%{"oAuth" => ["write"]}],
+ security: [%{"oAuth" => ["admin:write"]}],
requestBody: Helpers.request_body("Parameters", update_request()),
parameters: [
Operation.parameter(:name, :path, %Schema{type: :string}, "The document name",
@@ -77,7 +77,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.InstanceDocumentOperation do
tags: ["Instance documents"],
summary: "Delete an instance document",
operationId: "AdminAPI.InstanceDocumentController.delete",
- security: [%{"oAuth" => ["write"]}],
+ security: [%{"oAuth" => ["admin:write"]}],
parameters: [
Operation.parameter(:name, :path, %Schema{type: :string}, "The document name",
required: true
diff --git a/lib/pleroma/web/api_spec/operations/admin/invite_operation.ex b/lib/pleroma/web/api_spec/operations/admin/invite_operation.ex
index 60d69c767..704f082ba 100644
--- a/lib/pleroma/web/api_spec/operations/admin/invite_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/admin/invite_operation.ex
@@ -19,7 +19,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.InviteOperation do
tags: ["Invites"],
summary: "Get a list of generated invites",
operationId: "AdminAPI.InviteController.index",
- security: [%{"oAuth" => ["read:invites"]}],
+ security: [%{"oAuth" => ["admin:read:invites"]}],
parameters: admin_api_params(),
responses: %{
200 =>
@@ -51,7 +51,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.InviteOperation do
tags: ["Invites"],
summary: "Create an account registration invite token",
operationId: "AdminAPI.InviteController.create",
- security: [%{"oAuth" => ["write:invites"]}],
+ security: [%{"oAuth" => ["admin:write:invites"]}],
parameters: admin_api_params(),
requestBody:
request_body("Parameters", %Schema{
@@ -72,7 +72,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.InviteOperation do
tags: ["Invites"],
summary: "Revoke invite by token",
operationId: "AdminAPI.InviteController.revoke",
- security: [%{"oAuth" => ["write:invites"]}],
+ security: [%{"oAuth" => ["admin:write:invites"]}],
parameters: admin_api_params(),
requestBody:
request_body(
@@ -99,7 +99,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.InviteOperation do
tags: ["Invites"],
summary: "Sends registration invite via email",
operationId: "AdminAPI.InviteController.email",
- security: [%{"oAuth" => ["write:invites"]}],
+ security: [%{"oAuth" => ["admin:write:invites"]}],
parameters: admin_api_params(),
requestBody:
request_body(
diff --git a/lib/pleroma/web/api_spec/operations/admin/media_proxy_cache_operation.ex b/lib/pleroma/web/api_spec/operations/admin/media_proxy_cache_operation.ex
index 675504ee0..8f85ebf2d 100644
--- a/lib/pleroma/web/api_spec/operations/admin/media_proxy_cache_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/admin/media_proxy_cache_operation.ex
@@ -19,7 +19,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.MediaProxyCacheOperation do
tags: ["MediaProxy cache"],
summary: "Retrieve a list of banned MediaProxy URLs",
operationId: "AdminAPI.MediaProxyCacheController.index",
- security: [%{"oAuth" => ["read:media_proxy_caches"]}],
+ security: [%{"oAuth" => ["admin:read:media_proxy_caches"]}],
parameters: [
Operation.parameter(
:query,
@@ -71,7 +71,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.MediaProxyCacheOperation do
tags: ["MediaProxy cache"],
summary: "Remove a banned MediaProxy URL",
operationId: "AdminAPI.MediaProxyCacheController.delete",
- security: [%{"oAuth" => ["write:media_proxy_caches"]}],
+ security: [%{"oAuth" => ["admin:write:media_proxy_caches"]}],
parameters: admin_api_params(),
requestBody:
request_body(
@@ -97,7 +97,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.MediaProxyCacheOperation do
tags: ["MediaProxy cache"],
summary: "Purge a URL from MediaProxy cache and optionally ban it",
operationId: "AdminAPI.MediaProxyCacheController.purge",
- security: [%{"oAuth" => ["write:media_proxy_caches"]}],
+ security: [%{"oAuth" => ["admin:write:media_proxy_caches"]}],
parameters: admin_api_params(),
requestBody:
request_body(
diff --git a/lib/pleroma/web/api_spec/operations/admin/o_auth_app_operation.ex b/lib/pleroma/web/api_spec/operations/admin/o_auth_app_operation.ex
index 2f3bee4f0..35b029b19 100644
--- a/lib/pleroma/web/api_spec/operations/admin/o_auth_app_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/admin/o_auth_app_operation.ex
@@ -19,7 +19,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.OAuthAppOperation do
summary: "Retrieve a list of OAuth applications",
tags: ["OAuth application managment"],
operationId: "AdminAPI.OAuthAppController.index",
- security: [%{"oAuth" => ["write"]}],
+ security: [%{"oAuth" => ["admin:write"]}],
parameters: [
Operation.parameter(:name, :query, %Schema{type: :string}, "App name"),
Operation.parameter(:client_id, :query, %Schema{type: :string}, "Client ID"),
@@ -74,7 +74,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.OAuthAppOperation do
operationId: "AdminAPI.OAuthAppController.create",
requestBody: request_body("Parameters", create_request()),
parameters: admin_api_params(),
- security: [%{"oAuth" => ["write"]}],
+ security: [%{"oAuth" => ["admin:write"]}],
responses: %{
200 => Operation.response("App", "application/json", oauth_app()),
400 => Operation.response("Bad Request", "application/json", ApiError)
@@ -88,7 +88,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.OAuthAppOperation do
summary: "Update OAuth application",
operationId: "AdminAPI.OAuthAppController.update",
parameters: [id_param() | admin_api_params()],
- security: [%{"oAuth" => ["write"]}],
+ security: [%{"oAuth" => ["admin:write"]}],
requestBody: request_body("Parameters", update_request()),
responses: %{
200 => Operation.response("App", "application/json", oauth_app()),
@@ -106,7 +106,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.OAuthAppOperation do
summary: "Delete OAuth application",
operationId: "AdminAPI.OAuthAppController.delete",
parameters: [id_param() | admin_api_params()],
- security: [%{"oAuth" => ["write"]}],
+ security: [%{"oAuth" => ["admin:write"]}],
responses: %{
204 => no_content_response(),
400 => no_content_response()
diff --git a/lib/pleroma/web/api_spec/operations/admin/relay_operation.ex b/lib/pleroma/web/api_spec/operations/admin/relay_operation.ex
index c47f18f0c..c55c84fee 100644
--- a/lib/pleroma/web/api_spec/operations/admin/relay_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/admin/relay_operation.ex
@@ -18,7 +18,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.RelayOperation do
tags: ["Relays"],
summary: "Retrieve a list of relays",
operationId: "AdminAPI.RelayController.index",
- security: [%{"oAuth" => ["read"]}],
+ security: [%{"oAuth" => ["admin:read"]}],
parameters: admin_api_params(),
responses: %{
200 =>
@@ -40,7 +40,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.RelayOperation do
tags: ["Relays"],
summary: "Follow a relay",
operationId: "AdminAPI.RelayController.follow",
- security: [%{"oAuth" => ["write:follows"]}],
+ security: [%{"oAuth" => ["admin:write:follows"]}],
parameters: admin_api_params(),
requestBody: request_body("Parameters", relay_url()),
responses: %{
@@ -54,7 +54,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.RelayOperation do
tags: ["Relays"],
summary: "Unfollow a relay",
operationId: "AdminAPI.RelayController.unfollow",
- security: [%{"oAuth" => ["write:follows"]}],
+ security: [%{"oAuth" => ["admin:write:follows"]}],
parameters: admin_api_params(),
requestBody: request_body("Parameters", relay_unfollow()),
responses: %{
diff --git a/lib/pleroma/web/api_spec/operations/admin/report_operation.ex b/lib/pleroma/web/api_spec/operations/admin/report_operation.ex
index cfa892d29..8d7577505 100644
--- a/lib/pleroma/web/api_spec/operations/admin/report_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/admin/report_operation.ex
@@ -22,7 +22,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.ReportOperation do
tags: ["Report managment"],
summary: "Retrieve a list of reports",
operationId: "AdminAPI.ReportController.index",
- security: [%{"oAuth" => ["read:reports"]}],
+ security: [%{"oAuth" => ["admin:read:reports"]}],
parameters: [
Operation.parameter(
:state,
@@ -73,7 +73,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.ReportOperation do
summary: "Retrieve a report",
operationId: "AdminAPI.ReportController.show",
parameters: [id_param() | admin_api_params()],
- security: [%{"oAuth" => ["read:reports"]}],
+ security: [%{"oAuth" => ["admin:read:reports"]}],
responses: %{
200 => Operation.response("Report", "application/json", report()),
404 => Operation.response("Not Found", "application/json", ApiError)
@@ -86,7 +86,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.ReportOperation do
tags: ["Report managment"],
summary: "Change state of specified reports",
operationId: "AdminAPI.ReportController.update",
- security: [%{"oAuth" => ["write:reports"]}],
+ security: [%{"oAuth" => ["admin:write:reports"]}],
parameters: admin_api_params(),
requestBody: request_body("Parameters", update_request(), required: true),
responses: %{
@@ -110,7 +110,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.ReportOperation do
content: %Schema{type: :string, description: "The message"}
}
}),
- security: [%{"oAuth" => ["write:reports"]}],
+ security: [%{"oAuth" => ["admin:write:reports"]}],
responses: %{
204 => no_content_response(),
404 => Operation.response("Not Found", "application/json", ApiError)
@@ -128,7 +128,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.ReportOperation do
Operation.parameter(:id, :path, :string, "Note ID")
| admin_api_params()
],
- security: [%{"oAuth" => ["write:reports"]}],
+ security: [%{"oAuth" => ["admin:write:reports"]}],
responses: %{
204 => no_content_response(),
404 => Operation.response("Not Found", "application/json", ApiError)
@@ -136,11 +136,11 @@ defmodule Pleroma.Web.ApiSpec.Admin.ReportOperation do
}
end
- defp report_state do
+ def report_state do
%Schema{type: :string, enum: ["open", "closed", "resolved"]}
end
- defp id_param do
+ def id_param do
Operation.parameter(:id, :path, FlakeID, "Report ID",
example: "9umDrYheeY451cQnEe",
required: true
diff --git a/lib/pleroma/web/api_spec/operations/admin/status_operation.ex b/lib/pleroma/web/api_spec/operations/admin/status_operation.ex
index bbfbd8f93..d25ab5247 100644
--- a/lib/pleroma/web/api_spec/operations/admin/status_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/admin/status_operation.ex
@@ -24,7 +24,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.StatusOperation do
tags: ["Status administration"],
operationId: "AdminAPI.StatusController.index",
summary: "Get all statuses",
- security: [%{"oAuth" => ["read:statuses"]}],
+ security: [%{"oAuth" => ["admin:read:statuses"]}],
parameters: [
Operation.parameter(
:godmode,
@@ -74,7 +74,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.StatusOperation do
summary: "Get status",
operationId: "AdminAPI.StatusController.show",
parameters: [id_param() | admin_api_params()],
- security: [%{"oAuth" => ["read:statuses"]}],
+ security: [%{"oAuth" => ["admin:read:statuses"]}],
responses: %{
200 => Operation.response("Status", "application/json", status()),
404 => Operation.response("Not Found", "application/json", ApiError)
@@ -88,7 +88,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.StatusOperation do
summary: "Change the scope of a status",
operationId: "AdminAPI.StatusController.update",
parameters: [id_param() | admin_api_params()],
- security: [%{"oAuth" => ["write:statuses"]}],
+ security: [%{"oAuth" => ["admin:write:statuses"]}],
requestBody: request_body("Parameters", update_request(), required: true),
responses: %{
200 => Operation.response("Status", "application/json", Status),
@@ -103,7 +103,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.StatusOperation do
summary: "Delete status",
operationId: "AdminAPI.StatusController.delete",
parameters: [id_param() | admin_api_params()],
- security: [%{"oAuth" => ["write:statuses"]}],
+ security: [%{"oAuth" => ["admin:write:statuses"]}],
responses: %{
200 => empty_object_response(),
404 => Operation.response("Not Found", "application/json", ApiError)
diff --git a/lib/pleroma/web/api_spec/operations/admin/user_operation.ex b/lib/pleroma/web/api_spec/operations/admin/user_operation.ex
new file mode 100644
index 000000000..c9d0bfd7c
--- /dev/null
+++ b/lib/pleroma/web/api_spec/operations/admin/user_operation.ex
@@ -0,0 +1,389 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.ApiSpec.Admin.UserOperation do
+ alias OpenApiSpex.Operation
+ alias OpenApiSpex.Schema
+ alias Pleroma.Web.ApiSpec.Schemas.ActorType
+ alias Pleroma.Web.ApiSpec.Schemas.ApiError
+
+ import Pleroma.Web.ApiSpec.Helpers
+
+ def open_api_operation(action) do
+ operation = String.to_existing_atom("#{action}_operation")
+ apply(__MODULE__, operation, [])
+ end
+
+ def index_operation do
+ %Operation{
+ tags: ["User administration"],
+ summary: "List users",
+ operationId: "AdminAPI.UserController.index",
+ security: [%{"oAuth" => ["admin:read:accounts"]}],
+ parameters: [
+ Operation.parameter(:filters, :query, :string, "Comma separated list of filters"),
+ Operation.parameter(:query, :query, :string, "Search users query"),
+ Operation.parameter(:name, :query, :string, "Search by display name"),
+ Operation.parameter(:email, :query, :string, "Search by email"),
+ Operation.parameter(:page, :query, :integer, "Page Number"),
+ Operation.parameter(:page_size, :query, :integer, "Number of users to return per page"),
+ Operation.parameter(
+ :actor_types,
+ :query,
+ %Schema{type: :array, items: ActorType},
+ "Filter by actor type"
+ ),
+ Operation.parameter(
+ :tags,
+ :query,
+ %Schema{type: :array, items: %Schema{type: :string}},
+ "Filter by tags"
+ )
+ | admin_api_params()
+ ],
+ responses: %{
+ 200 =>
+ Operation.response(
+ "Response",
+ "application/json",
+ %Schema{
+ type: :object,
+ properties: %{
+ users: %Schema{type: :array, items: user()},
+ count: %Schema{type: :integer},
+ page_size: %Schema{type: :integer}
+ }
+ }
+ ),
+ 403 => Operation.response("Forbidden", "application/json", ApiError)
+ }
+ }
+ end
+
+ def create_operation do
+ %Operation{
+ tags: ["User administration"],
+ summary: "Create a single or multiple users",
+ operationId: "AdminAPI.UserController.create",
+ security: [%{"oAuth" => ["admin:write:accounts"]}],
+ parameters: admin_api_params(),
+ requestBody:
+ request_body(
+ "Parameters",
+ %Schema{
+ description: "POST body for creating users",
+ type: :object,
+ properties: %{
+ users: %Schema{
+ type: :array,
+ items: %Schema{
+ type: :object,
+ properties: %{
+ nickname: %Schema{type: :string},
+ email: %Schema{type: :string},
+ password: %Schema{type: :string}
+ }
+ }
+ }
+ }
+ }
+ ),
+ responses: %{
+ 200 =>
+ Operation.response("Response", "application/json", %Schema{
+ type: :array,
+ items: %Schema{
+ type: :object,
+ properties: %{
+ code: %Schema{type: :integer},
+ type: %Schema{type: :string},
+ data: %Schema{
+ type: :object,
+ properties: %{
+ email: %Schema{type: :string, format: :email},
+ nickname: %Schema{type: :string}
+ }
+ }
+ }
+ }
+ }),
+ 403 => Operation.response("Forbidden", "application/json", ApiError),
+ 409 =>
+ Operation.response("Conflict", "application/json", %Schema{
+ type: :array,
+ items: %Schema{
+ type: :object,
+ properties: %{
+ code: %Schema{type: :integer},
+ error: %Schema{type: :string},
+ type: %Schema{type: :string},
+ data: %Schema{
+ type: :object,
+ properties: %{
+ email: %Schema{type: :string, format: :email},
+ nickname: %Schema{type: :string}
+ }
+ }
+ }
+ }
+ })
+ }
+ }
+ end
+
+ def show_operation do
+ %Operation{
+ tags: ["User administration"],
+ summary: "Show user",
+ operationId: "AdminAPI.UserController.show",
+ security: [%{"oAuth" => ["admin:read:accounts"]}],
+ parameters: [
+ Operation.parameter(
+ :nickname,
+ :path,
+ :string,
+ "User nickname or ID"
+ )
+ | admin_api_params()
+ ],
+ responses: %{
+ 200 => Operation.response("Response", "application/json", user()),
+ 403 => Operation.response("Forbidden", "application/json", ApiError),
+ 404 => Operation.response("Not Found", "application/json", ApiError)
+ }
+ }
+ end
+
+ def follow_operation do
+ %Operation{
+ tags: ["User administration"],
+ summary: "Follow",
+ operationId: "AdminAPI.UserController.follow",
+ security: [%{"oAuth" => ["admin:write:follows"]}],
+ parameters: admin_api_params(),
+ requestBody:
+ request_body(
+ "Parameters",
+ %Schema{
+ type: :object,
+ properties: %{
+ follower: %Schema{type: :string, description: "Follower nickname"},
+ followed: %Schema{type: :string, description: "Followed nickname"}
+ }
+ }
+ ),
+ responses: %{
+ 200 => Operation.response("Response", "application/json", %Schema{type: :string}),
+ 403 => Operation.response("Forbidden", "application/json", ApiError)
+ }
+ }
+ end
+
+ def unfollow_operation do
+ %Operation{
+ tags: ["User administration"],
+ summary: "Unfollow",
+ operationId: "AdminAPI.UserController.unfollow",
+ security: [%{"oAuth" => ["admin:write:follows"]}],
+ parameters: admin_api_params(),
+ requestBody:
+ request_body(
+ "Parameters",
+ %Schema{
+ type: :object,
+ properties: %{
+ follower: %Schema{type: :string, description: "Follower nickname"},
+ followed: %Schema{type: :string, description: "Followed nickname"}
+ }
+ }
+ ),
+ responses: %{
+ 200 => Operation.response("Response", "application/json", %Schema{type: :string}),
+ 403 => Operation.response("Forbidden", "application/json", ApiError)
+ }
+ }
+ end
+
+ def approve_operation do
+ %Operation{
+ tags: ["User administration"],
+ summary: "Approve multiple users",
+ operationId: "AdminAPI.UserController.approve",
+ security: [%{"oAuth" => ["admin:write:accounts"]}],
+ parameters: admin_api_params(),
+ requestBody:
+ request_body(
+ "Parameters",
+ %Schema{
+ description: "POST body for deleting multiple users",
+ type: :object,
+ properties: %{
+ nicknames: %Schema{
+ type: :array,
+ items: %Schema{type: :string}
+ }
+ }
+ }
+ ),
+ responses: %{
+ 200 =>
+ Operation.response("Response", "application/json", %Schema{
+ type: :object,
+ properties: %{user: %Schema{type: :array, items: user()}}
+ }),
+ 403 => Operation.response("Forbidden", "application/json", ApiError)
+ }
+ }
+ end
+
+ def toggle_activation_operation do
+ %Operation{
+ tags: ["User administration"],
+ summary: "Toggle user activation",
+ operationId: "AdminAPI.UserController.toggle_activation",
+ security: [%{"oAuth" => ["admin:write:accounts"]}],
+ parameters: [
+ Operation.parameter(:nickname, :path, :string, "User nickname")
+ | admin_api_params()
+ ],
+ responses: %{
+ 200 => Operation.response("Response", "application/json", user()),
+ 403 => Operation.response("Forbidden", "application/json", ApiError)
+ }
+ }
+ end
+
+ def activate_operation do
+ %Operation{
+ tags: ["User administration"],
+ summary: "Activate multiple users",
+ operationId: "AdminAPI.UserController.activate",
+ security: [%{"oAuth" => ["admin:write:accounts"]}],
+ parameters: admin_api_params(),
+ requestBody:
+ request_body(
+ "Parameters",
+ %Schema{
+ description: "POST body for deleting multiple users",
+ type: :object,
+ properties: %{
+ nicknames: %Schema{
+ type: :array,
+ items: %Schema{type: :string}
+ }
+ }
+ }
+ ),
+ responses: %{
+ 200 =>
+ Operation.response("Response", "application/json", %Schema{
+ type: :object,
+ properties: %{user: %Schema{type: :array, items: user()}}
+ }),
+ 403 => Operation.response("Forbidden", "application/json", ApiError)
+ }
+ }
+ end
+
+ def deactivate_operation do
+ %Operation{
+ tags: ["User administration"],
+ summary: "Deactivates multiple users",
+ operationId: "AdminAPI.UserController.deactivate",
+ security: [%{"oAuth" => ["admin:write:accounts"]}],
+ parameters: admin_api_params(),
+ requestBody:
+ request_body(
+ "Parameters",
+ %Schema{
+ description: "POST body for deleting multiple users",
+ type: :object,
+ properties: %{
+ nicknames: %Schema{
+ type: :array,
+ items: %Schema{type: :string}
+ }
+ }
+ }
+ ),
+ responses: %{
+ 200 =>
+ Operation.response("Response", "application/json", %Schema{
+ type: :object,
+ properties: %{user: %Schema{type: :array, items: user()}}
+ }),
+ 403 => Operation.response("Forbidden", "application/json", ApiError)
+ }
+ }
+ end
+
+ def delete_operation do
+ %Operation{
+ tags: ["User administration"],
+ summary: "Removes a single or multiple users",
+ operationId: "AdminAPI.UserController.delete",
+ security: [%{"oAuth" => ["admin:write:accounts"]}],
+ parameters: [
+ Operation.parameter(
+ :nickname,
+ :query,
+ :string,
+ "User nickname"
+ )
+ | admin_api_params()
+ ],
+ requestBody:
+ request_body(
+ "Parameters",
+ %Schema{
+ description: "POST body for deleting multiple users",
+ type: :object,
+ properties: %{
+ nicknames: %Schema{
+ type: :array,
+ items: %Schema{type: :string}
+ }
+ }
+ }
+ ),
+ responses: %{
+ 200 =>
+ Operation.response("Response", "application/json", %Schema{
+ description: "Array of nicknames",
+ type: :array,
+ items: %Schema{type: :string}
+ }),
+ 403 => Operation.response("Forbidden", "application/json", ApiError)
+ }
+ }
+ end
+
+ defp user do
+ %Schema{
+ type: :object,
+ properties: %{
+ id: %Schema{type: :string},
+ email: %Schema{type: :string, format: :email},
+ avatar: %Schema{type: :string, format: :uri},
+ nickname: %Schema{type: :string},
+ display_name: %Schema{type: :string},
+ is_active: %Schema{type: :boolean},
+ local: %Schema{type: :boolean},
+ roles: %Schema{
+ type: :object,
+ properties: %{
+ admin: %Schema{type: :boolean},
+ moderator: %Schema{type: :boolean}
+ }
+ },
+ tags: %Schema{type: :array, items: %Schema{type: :string}},
+ is_confirmed: %Schema{type: :boolean},
+ is_approved: %Schema{type: :boolean},
+ url: %Schema{type: :string, format: :uri},
+ registration_reason: %Schema{type: :string, nullable: true},
+ actor_type: %Schema{type: :string}
+ }
+ }
+ end
+end
diff --git a/lib/pleroma/web/api_spec/operations/chat_operation.ex b/lib/pleroma/web/api_spec/operations/chat_operation.ex
index b49700172..23cb66392 100644
--- a/lib/pleroma/web/api_spec/operations/chat_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/chat_operation.ex
@@ -131,10 +131,32 @@ defmodule Pleroma.Web.ApiSpec.ChatOperation do
def index_operation do
%Operation{
tags: ["Chats"],
- summary: "Retrieve list of chats",
+ summary: "Retrieve list of chats (unpaginated)",
+ deprecated: true,
+ description:
+ "Deprecated due to no support for pagination. Using [/api/v2/pleroma/chats](#operation/ChatController.index2) instead is recommended.",
operationId: "ChatController.index",
parameters: [
Operation.parameter(:with_muted, :query, BooleanLike, "Include chats from muted users")
+ ],
+ responses: %{
+ 200 => Operation.response("The chats of the user", "application/json", chats_response())
+ },
+ security: [
+ %{
+ "oAuth" => ["read:chats"]
+ }
+ ]
+ }
+ end
+
+ def index2_operation do
+ %Operation{
+ tags: ["Chats"],
+ summary: "Retrieve list of chats",
+ operationId: "ChatController.index2",
+ parameters: [
+ Operation.parameter(:with_muted, :query, BooleanLike, "Include chats from muted users")
| pagination_params()
],
responses: %{
diff --git a/lib/pleroma/web/api_spec/operations/conversation_operation.ex b/lib/pleroma/web/api_spec/operations/conversation_operation.ex
index 367f4125a..17ed1af5e 100644
--- a/lib/pleroma/web/api_spec/operations/conversation_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/conversation_operation.ex
@@ -46,16 +46,31 @@ defmodule Pleroma.Web.ApiSpec.ConversationOperation do
tags: ["Conversations"],
summary: "Mark conversation as read",
operationId: "ConversationController.mark_as_read",
- parameters: [
- Operation.parameter(:id, :path, :string, "Conversation ID",
- example: "123",
- required: true
- )
- ],
+ parameters: [id_param()],
security: [%{"oAuth" => ["write:conversations"]}],
responses: %{
200 => Operation.response("Conversation", "application/json", Conversation)
}
}
end
+
+ def delete_operation do
+ %Operation{
+ tags: ["Conversations"],
+ summary: "Remove conversation",
+ operationId: "ConversationController.delete",
+ parameters: [id_param()],
+ security: [%{"oAuth" => ["write:conversations"]}],
+ responses: %{
+ 200 => empty_object_response()
+ }
+ }
+ end
+
+ def id_param do
+ Operation.parameter(:id, :path, :string, "Conversation ID",
+ example: "123",
+ required: true
+ )
+ end
end
diff --git a/lib/pleroma/web/api_spec/operations/pleroma_emoji_file_operation.ex b/lib/pleroma/web/api_spec/operations/pleroma_emoji_file_operation.ex
index bed9511ef..8c76096b5 100644
--- a/lib/pleroma/web/api_spec/operations/pleroma_emoji_file_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/pleroma_emoji_file_operation.ex
@@ -16,10 +16,10 @@ defmodule Pleroma.Web.ApiSpec.PleromaEmojiFileOperation do
def create_operation do
%Operation{
- tags: ["Emoji packs"],
+ tags: ["Emoji pack administration"],
summary: "Add new file to the pack",
operationId: "PleromaAPI.EmojiPackController.add_file",
- security: [%{"oAuth" => ["write"]}],
+ security: [%{"oAuth" => ["admin:write"]}],
requestBody: request_body("Parameters", create_request(), required: true),
parameters: [name_param()],
responses: %{
@@ -62,10 +62,10 @@ defmodule Pleroma.Web.ApiSpec.PleromaEmojiFileOperation do
def update_operation do
%Operation{
- tags: ["Emoji packs"],
+ tags: ["Emoji pack administration"],
summary: "Add new file to the pack",
operationId: "PleromaAPI.EmojiPackController.update_file",
- security: [%{"oAuth" => ["write"]}],
+ security: [%{"oAuth" => ["admin:write"]}],
requestBody: request_body("Parameters", update_request(), required: true),
parameters: [name_param()],
responses: %{
@@ -106,10 +106,10 @@ defmodule Pleroma.Web.ApiSpec.PleromaEmojiFileOperation do
def delete_operation do
%Operation{
- tags: ["Emoji packs"],
+ tags: ["Emoji pack administration"],
summary: "Delete emoji file from pack",
operationId: "PleromaAPI.EmojiPackController.delete_file",
- security: [%{"oAuth" => ["write"]}],
+ security: [%{"oAuth" => ["admin:write"]}],
parameters: [
name_param(),
Operation.parameter(:shortcode, :query, :string, "File shortcode",
diff --git a/lib/pleroma/web/api_spec/operations/pleroma_emoji_pack_operation.ex b/lib/pleroma/web/api_spec/operations/pleroma_emoji_pack_operation.ex
index 48dafa5f2..49247d9b6 100644
--- a/lib/pleroma/web/api_spec/operations/pleroma_emoji_pack_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/pleroma_emoji_pack_operation.ex
@@ -16,9 +16,9 @@ defmodule Pleroma.Web.ApiSpec.PleromaEmojiPackOperation do
def remote_operation do
%Operation{
- tags: ["Emoji packs"],
+ tags: ["Emoji pack administration"],
summary: "Make request to another instance for emoji packs list",
- security: [%{"oAuth" => ["write"]}],
+ security: [%{"oAuth" => ["admin:write"]}],
parameters: [
url_param(),
Operation.parameter(
@@ -115,10 +115,10 @@ defmodule Pleroma.Web.ApiSpec.PleromaEmojiPackOperation do
def download_operation do
%Operation{
- tags: ["Emoji packs"],
+ tags: ["Emoji pack administration"],
summary: "Download pack from another instance",
operationId: "PleromaAPI.EmojiPackController.download",
- security: [%{"oAuth" => ["write"]}],
+ security: [%{"oAuth" => ["admin:write"]}],
requestBody: request_body("Parameters", download_request(), required: true),
responses: %{
200 => ok_response(),
@@ -145,10 +145,10 @@ defmodule Pleroma.Web.ApiSpec.PleromaEmojiPackOperation do
def create_operation do
%Operation{
- tags: ["Emoji packs"],
+ tags: ["Emoji pack administration"],
summary: "Create an empty pack",
operationId: "PleromaAPI.EmojiPackController.create",
- security: [%{"oAuth" => ["write"]}],
+ security: [%{"oAuth" => ["admin:write"]}],
parameters: [name_param()],
responses: %{
200 => ok_response(),
@@ -161,10 +161,10 @@ defmodule Pleroma.Web.ApiSpec.PleromaEmojiPackOperation do
def delete_operation do
%Operation{
- tags: ["Emoji packs"],
+ tags: ["Emoji pack administration"],
summary: "Delete a custom emoji pack",
operationId: "PleromaAPI.EmojiPackController.delete",
- security: [%{"oAuth" => ["write"]}],
+ security: [%{"oAuth" => ["admin:write"]}],
parameters: [name_param()],
responses: %{
200 => ok_response(),
@@ -177,10 +177,10 @@ defmodule Pleroma.Web.ApiSpec.PleromaEmojiPackOperation do
def update_operation do
%Operation{
- tags: ["Emoji packs"],
+ tags: ["Emoji pack administration"],
summary: "Updates (replaces) pack metadata",
operationId: "PleromaAPI.EmojiPackController.update",
- security: [%{"oAuth" => ["write"]}],
+ security: [%{"oAuth" => ["admin:write"]}],
requestBody: request_body("Parameters", update_request(), required: true),
parameters: [name_param()],
responses: %{
@@ -193,10 +193,10 @@ defmodule Pleroma.Web.ApiSpec.PleromaEmojiPackOperation do
def import_from_filesystem_operation do
%Operation{
- tags: ["Emoji packs"],
+ tags: ["Emoji pack administration"],
summary: "Imports packs from filesystem",
operationId: "PleromaAPI.EmojiPackController.import",
- security: [%{"oAuth" => ["write"]}],
+ security: [%{"oAuth" => ["admin:write"]}],
responses: %{
200 =>
Operation.response("Array of imported pack names", "application/json", %Schema{
diff --git a/lib/pleroma/web/api_spec/operations/pleroma_report_operation.ex b/lib/pleroma/web/api_spec/operations/pleroma_report_operation.ex
new file mode 100644
index 000000000..ee8870dc2
--- /dev/null
+++ b/lib/pleroma/web/api_spec/operations/pleroma_report_operation.ex
@@ -0,0 +1,97 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.ApiSpec.PleromaReportOperation do
+ alias OpenApiSpex.Operation
+ alias OpenApiSpex.Schema
+ alias Pleroma.Web.ApiSpec.Admin.ReportOperation
+ alias Pleroma.Web.ApiSpec.Schemas.Account
+ alias Pleroma.Web.ApiSpec.Schemas.ApiError
+ alias Pleroma.Web.ApiSpec.Schemas.FlakeID
+ alias Pleroma.Web.ApiSpec.Schemas.Status
+
+ def open_api_operation(action) do
+ operation = String.to_existing_atom("#{action}_operation")
+ apply(__MODULE__, operation, [])
+ end
+
+ def index_operation do
+ %Operation{
+ tags: ["Reports"],
+ summary: "Get a list of your own reports",
+ operationId: "PleromaAPI.ReportController.index",
+ security: [%{"oAuth" => ["read:reports"]}],
+ parameters: [
+ Operation.parameter(
+ :state,
+ :query,
+ ReportOperation.report_state(),
+ "Filter by report state"
+ ),
+ Operation.parameter(
+ :limit,
+ :query,
+ %Schema{type: :integer},
+ "The number of records to retrieve"
+ ),
+ Operation.parameter(
+ :page,
+ :query,
+ %Schema{type: :integer, default: 1},
+ "Page number"
+ ),
+ Operation.parameter(
+ :page_size,
+ :query,
+ %Schema{type: :integer, default: 50},
+ "Number number of log entries per page"
+ )
+ ],
+ responses: %{
+ 200 =>
+ Operation.response("Response", "application/json", %Schema{
+ type: :object,
+ properties: %{
+ total: %Schema{type: :integer},
+ reports: %Schema{
+ type: :array,
+ items: report()
+ }
+ }
+ }),
+ 404 => Operation.response("Not Found", "application/json", ApiError)
+ }
+ }
+ end
+
+ def show_operation do
+ %Operation{
+ tags: ["Reports"],
+ summary: "Get an individual report",
+ operationId: "PleromaAPI.ReportController.show",
+ parameters: [ReportOperation.id_param()],
+ security: [%{"oAuth" => ["read:reports"]}],
+ responses: %{
+ 200 => Operation.response("Report", "application/json", report()),
+ 404 => Operation.response("Not Found", "application/json", ApiError)
+ }
+ }
+ end
+
+ # Copied from ReportOperation.report with removing notes
+ defp report do
+ %Schema{
+ type: :object,
+ properties: %{
+ id: FlakeID,
+ state: ReportOperation.report_state(),
+ account: Account,
+ actor: Account,
+ content: %Schema{type: :string},
+ created_at: %Schema{type: :string, format: :"date-time"},
+ statuses: %Schema{type: :array, items: Status}
+ }
+ }
+ end
+end
diff --git a/lib/pleroma/web/api_spec/operations/status_operation.ex b/lib/pleroma/web/api_spec/operations/status_operation.ex
index 40edc747d..4bdb8e281 100644
--- a/lib/pleroma/web/api_spec/operations/status_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/status_operation.ex
@@ -59,7 +59,7 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
Operation.response(
"Status. When `scheduled_at` is present, ScheduledStatus is returned instead",
"application/json",
- %Schema{oneOf: [Status, ScheduledStatus]}
+ %Schema{anyOf: [Status, ScheduledStatus]}
),
422 => Operation.response("Bad Request / MRF Rejection", "application/json", ApiError)
}
diff --git a/lib/pleroma/web/api_spec/schemas/boolean_like.ex b/lib/pleroma/web/api_spec/schemas/boolean_like.ex
index eb001c5bb..778158f66 100644
--- a/lib/pleroma/web/api_spec/schemas/boolean_like.ex
+++ b/lib/pleroma/web/api_spec/schemas/boolean_like.ex
@@ -3,6 +3,7 @@
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ApiSpec.Schemas.BooleanLike do
+ alias OpenApiSpex.Cast
alias OpenApiSpex.Schema
require OpenApiSpex
@@ -27,10 +28,13 @@ defmodule Pleroma.Web.ApiSpec.Schemas.BooleanLike do
%Schema{type: :boolean},
%Schema{type: :string},
%Schema{type: :integer}
- ]
+ ],
+ "x-validate": __MODULE__
})
- def after_cast(value, _schmea) do
- {:ok, Pleroma.Web.ControllerHelper.truthy_param?(value)}
+ def cast(%Cast{value: value} = context) do
+ context
+ |> Map.put(:value, Pleroma.Web.ControllerHelper.truthy_param?(value))
+ |> Cast.ok()
end
end
diff --git a/lib/pleroma/web/api_spec/schemas/chat_message.ex b/lib/pleroma/web/api_spec/schemas/chat_message.ex
index 6986b9c17..348fe95f8 100644
--- a/lib/pleroma/web/api_spec/schemas/chat_message.ex
+++ b/lib/pleroma/web/api_spec/schemas/chat_message.ex
@@ -52,7 +52,8 @@ defmodule Pleroma.Web.ApiSpec.Schemas.ChatMessage do
title: %Schema{type: :string, description: "Title of linked resource"},
description: %Schema{type: :string, description: "Description of preview"}
}
- }
+ },
+ unread: %Schema{type: :boolean, description: "Whether a message has been marked as read."}
},
example: %{
"account_id" => "someflakeid",
@@ -69,7 +70,8 @@ defmodule Pleroma.Web.ApiSpec.Schemas.ChatMessage do
}
],
"id" => "14",
- "attachment" => nil
+ "attachment" => nil,
+ "unread" => false
}
})
end
diff --git a/lib/pleroma/web/api_spec/schemas/scheduled_status.ex b/lib/pleroma/web/api_spec/schemas/scheduled_status.ex
index cc051046a..607586e32 100644
--- a/lib/pleroma/web/api_spec/schemas/scheduled_status.ex
+++ b/lib/pleroma/web/api_spec/schemas/scheduled_status.ex
@@ -30,7 +30,8 @@ defmodule Pleroma.Web.ApiSpec.Schemas.ScheduledStatus do
visibility: %Schema{allOf: [VisibilityScope], nullable: true},
scheduled_at: %Schema{type: :string, format: :"date-time", nullable: true},
poll: StatusOperation.poll_params(),
- in_reply_to_id: %Schema{type: :string, nullable: true}
+ in_reply_to_id: %Schema{type: :string, nullable: true},
+ expires_in: %Schema{type: :integer, nullable: true}
}
}
},
@@ -46,7 +47,8 @@ defmodule Pleroma.Web.ApiSpec.Schemas.ScheduledStatus do
scheduled_at: nil,
poll: nil,
idempotency: nil,
- in_reply_to_id: nil
+ in_reply_to_id: nil,
+ expires_in: nil
},
media_attachments: [Attachment.schema().example]
}
diff --git a/lib/pleroma/web/api_spec/schemas/status.ex b/lib/pleroma/web/api_spec/schemas/status.ex
index 61ebd8089..42fa98718 100644
--- a/lib/pleroma/web/api_spec/schemas/status.ex
+++ b/lib/pleroma/web/api_spec/schemas/status.ex
@@ -23,9 +23,10 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Status do
application: %Schema{
description: "The application used to post this status",
type: :object,
+ nullable: true,
properties: %{
name: %Schema{type: :string},
- website: %Schema{type: :string, nullable: true, format: :uri}
+ website: %Schema{type: :string, format: :uri}
}
},
bookmarked: %Schema{type: :boolean, description: "Have you bookmarked this status?"},
@@ -291,7 +292,7 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Status do
"url" => "http://localhost:4001/users/nick6",
"username" => "nick6"
},
- "application" => %{"name" => "Web", "website" => nil},
+ "application" => nil,
"bookmarked" => false,
"card" => nil,
"content" => "foobar",
diff --git a/lib/pleroma/web/common_api/activity_draft.ex b/lib/pleroma/web/common_api/activity_draft.ex
index da726a690..8668b600e 100644
--- a/lib/pleroma/web/common_api/activity_draft.ex
+++ b/lib/pleroma/web/common_api/activity_draft.ex
@@ -190,6 +190,7 @@ defmodule Pleroma.Web.CommonAPI.ActivityDraft do
Utils.make_note_data(draft)
|> Map.put("emoji", emoji)
|> Map.put("source", draft.status)
+ |> Map.put("generator", draft.params[:generator])
%__MODULE__{draft | object: object}
end
diff --git a/lib/pleroma/web/fallback/legacy_pleroma_api_rerouter_plug.ex b/lib/pleroma/web/fallback/legacy_pleroma_api_rerouter_plug.ex
new file mode 100644
index 000000000..f86d6b52b
--- /dev/null
+++ b/lib/pleroma/web/fallback/legacy_pleroma_api_rerouter_plug.ex
@@ -0,0 +1,26 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.Fallback.LegacyPleromaApiRerouterPlug do
+ alias Pleroma.Web.Endpoint
+ alias Pleroma.Web.Fallback.RedirectController
+
+ def init(opts), do: opts
+
+ def call(%{path_info: ["api", "pleroma" | path_info_rest]} = conn, _opts) do
+ new_path_info = ["api", "v1", "pleroma" | path_info_rest]
+ new_request_path = Enum.join(new_path_info, "/")
+
+ conn
+ |> Map.merge(%{
+ path_info: new_path_info,
+ request_path: new_request_path
+ })
+ |> Endpoint.call(conn.params)
+ end
+
+ def call(conn, _opts) do
+ RedirectController.api_not_implemented(conn, %{})
+ end
+end
diff --git a/lib/pleroma/web/mastodon_api/controllers/app_controller.ex b/lib/pleroma/web/mastodon_api/controllers/app_controller.ex
index a7e4d93f5..dd3b39c77 100644
--- a/lib/pleroma/web/mastodon_api/controllers/app_controller.ex
+++ b/lib/pleroma/web/mastodon_api/controllers/app_controller.ex
@@ -3,6 +3,11 @@
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.MastodonAPI.AppController do
+ @moduledoc """
+ Controller for supporting app-related actions.
+ If authentication is an option, app tokens (user-unbound) must be supported.
+ """
+
use Pleroma.Web, :controller
alias Pleroma.Repo
@@ -17,11 +22,9 @@ defmodule Pleroma.Web.MastodonAPI.AppController do
plug(
:skip_plug,
[OAuthScopesPlug, EnsurePublicOrAuthenticatedPlug]
- when action == :create
+ when action in [:create, :verify_credentials]
)
- plug(OAuthScopesPlug, %{scopes: ["read"]} when action == :verify_credentials)
-
plug(Pleroma.Web.ApiSpec.CastAndValidate)
@local_mastodon_name "Mastodon-Local"
@@ -44,10 +47,13 @@ defmodule Pleroma.Web.MastodonAPI.AppController do
end
end
- @doc "GET /api/v1/apps/verify_credentials"
- def verify_credentials(%{assigns: %{user: _user, token: token}} = conn, _) do
- with %Token{app: %App{} = app} <- Repo.preload(token, :app) do
- render(conn, "short.json", app: app)
+ @doc """
+ GET /api/v1/apps/verify_credentials
+ Gets compact non-secret representation of the app. Supports app tokens and user tokens.
+ """
+ def verify_credentials(%{assigns: %{token: %Token{} = token}} = conn, _) do
+ with %{app: %App{} = app} <- Repo.preload(token, :app) do
+ render(conn, "compact_non_secret.json", app: app)
end
end
end
diff --git a/lib/pleroma/web/mastodon_api/controllers/conversation_controller.ex b/lib/pleroma/web/mastodon_api/controllers/conversation_controller.ex
index 4526d3c7a..f2a0949e8 100644
--- a/lib/pleroma/web/mastodon_api/controllers/conversation_controller.ex
+++ b/lib/pleroma/web/mastodon_api/controllers/conversation_controller.ex
@@ -36,4 +36,13 @@ defmodule Pleroma.Web.MastodonAPI.ConversationController do
render(conn, "participation.json", participation: participation, for: user)
end
end
+
+ @doc "DELETE /api/v1/conversations/:id"
+ def delete(%{assigns: %{user: user}} = conn, %{id: participation_id}) do
+ with %Participation{} = participation <-
+ Repo.get_by(Participation, id: participation_id, user_id: user.id),
+ {:ok, _} <- Participation.delete(participation) do
+ json(conn, %{})
+ end
+ end
end
diff --git a/lib/pleroma/web/mastodon_api/controllers/instance_controller.ex b/lib/pleroma/web/mastodon_api/controllers/instance_controller.ex
index 267d0f03b..c7a5267d4 100644
--- a/lib/pleroma/web/mastodon_api/controllers/instance_controller.ex
+++ b/lib/pleroma/web/mastodon_api/controllers/instance_controller.ex
@@ -5,7 +5,7 @@
defmodule Pleroma.Web.MastodonAPI.InstanceController do
use Pleroma.Web, :controller
- plug(OpenApiSpex.Plug.CastAndValidate)
+ plug(Pleroma.Web.ApiSpec.CastAndValidate)
plug(
:skip_plug,
diff --git a/lib/pleroma/web/mastodon_api/controllers/status_controller.ex b/lib/pleroma/web/mastodon_api/controllers/status_controller.ex
index 4cf2ee35c..b051fca74 100644
--- a/lib/pleroma/web/mastodon_api/controllers/status_controller.ex
+++ b/lib/pleroma/web/mastodon_api/controllers/status_controller.ex
@@ -21,6 +21,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.MastodonAPI.AccountView
alias Pleroma.Web.MastodonAPI.ScheduledActivityView
+ alias Pleroma.Web.OAuth.Token
alias Pleroma.Web.Plugs.OAuthScopesPlug
alias Pleroma.Web.Plugs.RateLimiter
@@ -138,7 +139,9 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
_
)
when not is_nil(scheduled_at) do
- params = Map.put(params, :in_reply_to_status_id, params[:in_reply_to_id])
+ params =
+ Map.put(params, :in_reply_to_status_id, params[:in_reply_to_id])
+ |> put_application(conn)
attrs = %{
params: Map.new(params, fn {key, value} -> {to_string(key), value} end),
@@ -162,7 +165,9 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
# Creates a regular status
def create(%{assigns: %{user: user}, body_params: %{status: _} = params} = conn, _) do
- params = Map.put(params, :in_reply_to_status_id, params[:in_reply_to_id])
+ params =
+ Map.put(params, :in_reply_to_status_id, params[:in_reply_to_id])
+ |> put_application(conn)
with {:ok, activity} <- CommonAPI.post(user, params) do
try_render(conn, "show.json",
@@ -414,4 +419,15 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
as: :activity
)
end
+
+ defp put_application(params, %{assigns: %{token: %Token{user: %User{} = user} = token}} = _conn) do
+ if user.disclose_client do
+ %{client_name: client_name, website: website} = Repo.preload(token, :app).app
+ Map.put(params, :generator, %{type: "Application", name: client_name, url: website})
+ else
+ Map.put(params, :generator, nil)
+ end
+ end
+
+ defp put_application(params, _), do: Map.put(params, :generator, nil)
end
diff --git a/lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex b/lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex
index 87effa00b..c611958be 100644
--- a/lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex
+++ b/lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex
@@ -133,34 +133,25 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
end
defp hashtag_fetching(params, user, local_only) do
- tags =
+ # Note: not sanitizing tag options at this stage (may be mix-cased, have duplicates etc.)
+ tags_any =
[params[:tag], params[:any]]
|> List.flatten()
- |> Enum.reject(&is_nil/1)
- |> Enum.map(&String.downcase/1)
- |> Enum.uniq()
-
- tag_all =
- params
- |> Map.get(:all, [])
- |> Enum.map(&String.downcase/1)
-
- tag_reject =
- params
- |> Map.get(:none, [])
- |> Enum.map(&String.downcase/1)
-
- _activities =
- params
- |> Map.put(:type, "Create")
- |> Map.put(:local_only, local_only)
- |> Map.put(:blocking_user, user)
- |> Map.put(:muting_user, user)
- |> Map.put(:user, user)
- |> Map.put(:tag, tags)
- |> Map.put(:tag_all, tag_all)
- |> Map.put(:tag_reject, tag_reject)
- |> ActivityPub.fetch_public_activities()
+ |> Enum.filter(& &1)
+
+ tag_all = Map.get(params, :all, [])
+ tag_reject = Map.get(params, :none, [])
+
+ params
+ |> Map.put(:type, "Create")
+ |> Map.put(:local_only, local_only)
+ |> Map.put(:blocking_user, user)
+ |> Map.put(:muting_user, user)
+ |> Map.put(:user, user)
+ |> Map.put(:tag, tags_any)
+ |> Map.put(:tag_all, tag_all)
+ |> Map.put(:tag_reject, tag_reject)
+ |> ActivityPub.fetch_public_activities()
end
# GET /api/v1/timelines/tag/:tag
diff --git a/lib/pleroma/web/mastodon_api/views/app_view.ex b/lib/pleroma/web/mastodon_api/views/app_view.ex
index 3d7131e09..c406b5a27 100644
--- a/lib/pleroma/web/mastodon_api/views/app_view.ex
+++ b/lib/pleroma/web/mastodon_api/views/app_view.ex
@@ -34,10 +34,10 @@ defmodule Pleroma.Web.MastodonAPI.AppView do
|> with_vapid_key()
end
- def render("short.json", %{app: %App{website: webiste, client_name: name}}) do
+ def render("compact_non_secret.json", %{app: %App{website: website, client_name: name}}) do
%{
name: name,
- website: webiste
+ website: website
}
|> with_vapid_key()
end
diff --git a/lib/pleroma/web/mastodon_api/views/scheduled_activity_view.ex b/lib/pleroma/web/mastodon_api/views/scheduled_activity_view.ex
index 13774d237..453221f41 100644
--- a/lib/pleroma/web/mastodon_api/views/scheduled_activity_view.ex
+++ b/lib/pleroma/web/mastodon_api/views/scheduled_activity_view.ex
@@ -37,7 +37,8 @@ defmodule Pleroma.Web.MastodonAPI.ScheduledActivityView do
visibility: params["visibility"],
scheduled_at: params["scheduled_at"],
poll: params["poll"],
- in_reply_to_id: params["in_reply_to_id"]
+ in_reply_to_id: params["in_reply_to_id"],
+ expires_in: params["expires_in"]
}
|> Pleroma.Maps.put_if_present(:media_ids, params["media_ids"])
end
diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex
index bbe0b11ec..d30c9fa68 100644
--- a/lib/pleroma/web/mastodon_api/views/status_view.ex
+++ b/lib/pleroma/web/mastodon_api/views/status_view.ex
@@ -124,16 +124,16 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
) do
user = CommonAPI.get_user(activity.data["actor"])
created_at = Utils.to_masto_date(activity.data["published"])
- activity_object = Object.normalize(activity, fetch: false)
+ object = Object.normalize(activity, fetch: false)
reblogged_parent_activity =
if opts[:parent_activities] do
Activity.Queries.find_by_object_ap_id(
opts[:parent_activities],
- activity_object.data["id"]
+ object.data["id"]
)
else
- Activity.create_by_object_ap_id(activity_object.data["id"])
+ Activity.create_by_object_ap_id(object.data["id"])
|> Activity.with_preloaded_bookmark(opts[:for])
|> Activity.with_set_thread_muted_field(opts[:for])
|> Repo.one()
@@ -142,7 +142,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
reblog_rendering_opts = Map.put(opts, :activity, reblogged_parent_activity)
reblogged = render("show.json", reblog_rendering_opts)
- favorited = opts[:for] && opts[:for].ap_id in (activity_object.data["likes"] || [])
+ favorited = opts[:for] && opts[:for].ap_id in (object.data["likes"] || [])
bookmarked = Activity.get_bookmark(reblogged_parent_activity, opts[:for]) != nil
@@ -154,8 +154,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
%{
id: to_string(activity.id),
- uri: activity_object.data["id"],
- url: activity_object.data["id"],
+ uri: object.data["id"],
+ url: object.data["id"],
account:
AccountView.render("show.json", %{
user: user,
@@ -180,10 +180,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
media_attachments: reblogged[:media_attachments] || [],
mentions: mentions,
tags: reblogged[:tags] || [],
- application: %{
- name: "Web",
- website: nil
- },
+ application: build_application(object.data["generator"]),
language: nil,
emojis: [],
pleroma: %{
@@ -350,10 +347,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
poll: render(PollView, "show.json", object: object, for: opts[:for]),
mentions: mentions,
tags: build_tags(tags),
- application: %{
- name: "Web",
- website: nil
- },
+ application: build_application(object.data["generator"]),
language: nil,
emojis: build_emojis(object.data["emoji"]),
pleroma: %{
@@ -542,4 +536,10 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
me: !!(current_user && current_user.ap_id in users)
}
end
+
+ @spec build_application(map() | nil) :: map() | nil
+ defp build_application(%{"type" => _type, "name" => name, "url" => url}),
+ do: %{name: name, website: url}
+
+ defp build_application(_), do: nil
end
diff --git a/lib/pleroma/web/pleroma_api/controllers/backup_controller.ex b/lib/pleroma/web/pleroma_api/controllers/backup_controller.ex
index 315657e9c..fc5d16771 100644
--- a/lib/pleroma/web/pleroma_api/controllers/backup_controller.ex
+++ b/lib/pleroma/web/pleroma_api/controllers/backup_controller.ex
@@ -10,7 +10,7 @@ defmodule Pleroma.Web.PleromaAPI.BackupController do
action_fallback(Pleroma.Web.MastodonAPI.FallbackController)
plug(OAuthScopesPlug, %{scopes: ["read:accounts"]} when action in [:index, :create])
- plug(OpenApiSpex.Plug.CastAndValidate, render_error: Pleroma.Web.ApiSpec.RenderError)
+ plug(Pleroma.Web.ApiSpec.CastAndValidate)
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.PleromaBackupOperation
diff --git a/lib/pleroma/web/pleroma_api/controllers/chat_controller.ex b/lib/pleroma/web/pleroma_api/controllers/chat_controller.ex
index f3cd1fbf6..dcd54b1af 100644
--- a/lib/pleroma/web/pleroma_api/controllers/chat_controller.ex
+++ b/lib/pleroma/web/pleroma_api/controllers/chat_controller.ex
@@ -35,10 +35,10 @@ defmodule Pleroma.Web.PleromaAPI.ChatController do
plug(
OAuthScopesPlug,
- %{scopes: ["read:chats"]} when action in [:messages, :index, :show]
+ %{scopes: ["read:chats"]} when action in [:messages, :index, :index2, :show]
)
- plug(OpenApiSpex.Plug.CastAndValidate, render_error: Pleroma.Web.ApiSpec.RenderError)
+ plug(Pleroma.Web.ApiSpec.CastAndValidate)
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.ChatOperation
@@ -138,20 +138,32 @@ defmodule Pleroma.Web.PleromaAPI.ChatController do
end
end
- def index(%{assigns: %{user: %{id: user_id} = user}} = conn, params) do
- exclude_users =
- User.cached_blocked_users_ap_ids(user) ++
- if params[:with_muted], do: [], else: User.cached_muted_users_ap_ids(user)
-
+ def index(%{assigns: %{user: user}} = conn, params) do
chats =
- user_id
- |> Chat.for_user_query()
- |> where([c], c.recipient not in ^exclude_users)
+ index_query(user, params)
|> Repo.all()
render(conn, "index.json", chats: chats)
end
+ def index2(%{assigns: %{user: user}} = conn, params) do
+ chats =
+ index_query(user, params)
+ |> Pagination.fetch_paginated(params)
+
+ render(conn, "index.json", chats: chats)
+ end
+
+ defp index_query(%{id: user_id} = user, params) do
+ exclude_users =
+ User.cached_blocked_users_ap_ids(user) ++
+ if params[:with_muted], do: [], else: User.cached_muted_users_ap_ids(user)
+
+ user_id
+ |> Chat.for_user_query()
+ |> where([c], c.recipient not in ^exclude_users)
+ end
+
def create(%{assigns: %{user: user}} = conn, %{id: id}) do
with %User{ap_id: recipient} <- User.get_cached_by_id(id),
{:ok, %Chat{} = chat} <- Chat.get_or_create(user.id, recipient) do
diff --git a/lib/pleroma/web/pleroma_api/controllers/emoji_file_controller.ex b/lib/pleroma/web/pleroma_api/controllers/emoji_file_controller.ex
index 6a41bbab4..204e81311 100644
--- a/lib/pleroma/web/pleroma_api/controllers/emoji_file_controller.ex
+++ b/lib/pleroma/web/pleroma_api/controllers/emoji_file_controller.ex
@@ -12,7 +12,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiFileController do
plug(
Pleroma.Web.Plugs.OAuthScopesPlug,
- %{scopes: ["write"], admin: true}
+ %{scopes: ["admin:write"]}
when action in [
:create,
:update,
diff --git a/lib/pleroma/web/pleroma_api/controllers/emoji_pack_controller.ex b/lib/pleroma/web/pleroma_api/controllers/emoji_pack_controller.ex
index c696241f0..d0f677d3c 100644
--- a/lib/pleroma/web/pleroma_api/controllers/emoji_pack_controller.ex
+++ b/lib/pleroma/web/pleroma_api/controllers/emoji_pack_controller.ex
@@ -11,7 +11,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiPackController do
plug(
Pleroma.Web.Plugs.OAuthScopesPlug,
- %{scopes: ["write"], admin: true}
+ %{scopes: ["admin:write"]}
when action in [
:import_from_filesystem,
:remote,
diff --git a/lib/pleroma/web/pleroma_api/controllers/report_controller.ex b/lib/pleroma/web/pleroma_api/controllers/report_controller.ex
new file mode 100644
index 000000000..d93d7570a
--- /dev/null
+++ b/lib/pleroma/web/pleroma_api/controllers/report_controller.ex
@@ -0,0 +1,46 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.PleromaAPI.ReportController do
+ use Pleroma.Web, :controller
+
+ alias Pleroma.Activity
+ alias Pleroma.Web.ActivityPub.Utils
+ alias Pleroma.Web.AdminAPI.Report
+
+ action_fallback(Pleroma.Web.MastodonAPI.FallbackController)
+ plug(Pleroma.Web.ApiSpec.CastAndValidate)
+ plug(Pleroma.Web.Plugs.OAuthScopesPlug, %{scopes: ["read:reports"]})
+
+ defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.PleromaReportOperation
+
+ @doc "GET /api/v0/pleroma/reports"
+ def index(%{assigns: %{user: user}, body_params: params} = conn, _) do
+ params =
+ params
+ |> Map.put(:actor_id, user.ap_id)
+
+ reports = Utils.get_reports(params, Map.get(params, :page, 1), Map.get(params, :size, 20))
+
+ render(conn, "index.json", %{reports: reports, for: user})
+ end
+
+ @doc "GET /api/v0/pleroma/reports/:id"
+ def show(%{assigns: %{user: user}} = conn, %{id: id}) do
+ with %Activity{} = report <- Activity.get_report(id),
+ true <- report.actor == user.ap_id,
+ %{} = report_info <- Report.extract_report_info(report) do
+ render(conn, "show.json", Map.put(report_info, :for, user))
+ else
+ false ->
+ {:error, :not_found}
+
+ nil ->
+ {:error, :not_found}
+
+ e ->
+ {:error, inspect(e)}
+ end
+ end
+end
diff --git a/lib/pleroma/web/pleroma_api/controllers/user_import_controller.ex b/lib/pleroma/web/pleroma_api/controllers/user_import_controller.ex
index 6d9a11fb6..078d470d9 100644
--- a/lib/pleroma/web/pleroma_api/controllers/user_import_controller.ex
+++ b/lib/pleroma/web/pleroma_api/controllers/user_import_controller.ex
@@ -15,7 +15,7 @@ defmodule Pleroma.Web.PleromaAPI.UserImportController do
plug(OAuthScopesPlug, %{scopes: ["follow", "write:blocks"]} when action == :blocks)
plug(OAuthScopesPlug, %{scopes: ["follow", "write:mutes"]} when action == :mutes)
- plug(OpenApiSpex.Plug.CastAndValidate)
+ plug(Pleroma.Web.ApiSpec.CastAndValidate)
defdelegate open_api_operation(action), to: ApiSpec.UserImportOperation
def follow(%{body_params: %{list: %Plug.Upload{path: path}}} = conn, _) do
diff --git a/lib/pleroma/web/pleroma_api/views/report_view.ex b/lib/pleroma/web/pleroma_api/views/report_view.ex
new file mode 100644
index 000000000..a0b3f085c
--- /dev/null
+++ b/lib/pleroma/web/pleroma_api/views/report_view.ex
@@ -0,0 +1,55 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.PleromaAPI.ReportView do
+ use Pleroma.Web, :view
+
+ alias Pleroma.HTML
+ alias Pleroma.Web.AdminAPI.Report
+ alias Pleroma.Web.CommonAPI.Utils
+ alias Pleroma.Web.MastodonAPI.AccountView
+ alias Pleroma.Web.MastodonAPI.StatusView
+
+ def render("index.json", %{reports: reports, for: for_user}) do
+ %{
+ reports:
+ reports[:items]
+ |> Enum.map(&Report.extract_report_info/1)
+ |> Enum.map(&render(__MODULE__, "show.json", Map.put(&1, :for, for_user))),
+ total: reports[:total]
+ }
+ end
+
+ def render("show.json", %{
+ report: report,
+ user: actor,
+ account: account,
+ statuses: statuses,
+ for: for_user
+ }) do
+ created_at = Utils.to_masto_date(report.data["published"])
+
+ content =
+ unless is_nil(report.data["content"]) do
+ HTML.filter_tags(report.data["content"])
+ else
+ nil
+ end
+
+ %{
+ id: report.id,
+ account: AccountView.render("show.json", %{user: account, for: for_user}),
+ actor: AccountView.render("show.json", %{user: actor, for: for_user}),
+ content: content,
+ created_at: created_at,
+ statuses:
+ StatusView.render("index.json", %{
+ activities: statuses,
+ as: :activity,
+ for: for_user
+ }),
+ state: report.data["state"]
+ }
+ end
+end
diff --git a/lib/pleroma/web/plugs/ensure_authenticated_plug.ex b/lib/pleroma/web/plugs/ensure_authenticated_plug.ex
index a4b5dc257..31e7410d6 100644
--- a/lib/pleroma/web/plugs/ensure_authenticated_plug.ex
+++ b/lib/pleroma/web/plugs/ensure_authenticated_plug.ex
@@ -3,6 +3,10 @@
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Plugs.EnsureAuthenticatedPlug do
+ @moduledoc """
+ Ensures _user_ authentication (app-bound user-unbound tokens are not accepted).
+ """
+
import Plug.Conn
import Pleroma.Web.TranslationHelpers
diff --git a/lib/pleroma/web/plugs/ensure_public_or_authenticated_plug.ex b/lib/pleroma/web/plugs/ensure_public_or_authenticated_plug.ex
index b6dfc4f3c..8a8532f41 100644
--- a/lib/pleroma/web/plugs/ensure_public_or_authenticated_plug.ex
+++ b/lib/pleroma/web/plugs/ensure_public_or_authenticated_plug.ex
@@ -3,6 +3,11 @@
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Plugs.EnsurePublicOrAuthenticatedPlug do
+ @moduledoc """
+ Ensures instance publicity or _user_ authentication
+ (app-bound user-unbound tokens are accepted only if the instance is public).
+ """
+
import Pleroma.Web.TranslationHelpers
import Plug.Conn
diff --git a/lib/pleroma/web/plugs/ensure_user_token_assigns_plug.ex b/lib/pleroma/web/plugs/ensure_user_token_assigns_plug.ex
index 3a2b5dda8..534b0cff1 100644
--- a/lib/pleroma/web/plugs/ensure_user_token_assigns_plug.ex
+++ b/lib/pleroma/web/plugs/ensure_user_token_assigns_plug.ex
@@ -28,6 +28,11 @@ defmodule Pleroma.Web.Plugs.EnsureUserTokenAssignsPlug do
end
end
+ # App-bound token case (obtained with client_id and client_secret)
+ def call(%{assigns: %{token: %Token{user_id: nil}}} = conn, _) do
+ assign(conn, :user, nil)
+ end
+
def call(conn, _) do
conn
|> assign(:user, nil)
diff --git a/lib/pleroma/web/plugs/frontend_static.ex b/lib/pleroma/web/plugs/frontend_static.ex
index eecf16264..eb385e94d 100644
--- a/lib/pleroma/web/plugs/frontend_static.ex
+++ b/lib/pleroma/web/plugs/frontend_static.ex
@@ -10,6 +10,8 @@ defmodule Pleroma.Web.Plugs.FrontendStatic do
"""
@behaviour Plug
+ @api_routes Pleroma.Web.get_api_routes()
+
def file_path(path, frontend_type \\ :primary) do
if configuration = Pleroma.Config.get([:frontends, frontend_type]) do
instance_static_path = Pleroma.Config.get([:instance, :static_dir], "instance/static")
@@ -34,7 +36,8 @@ defmodule Pleroma.Web.Plugs.FrontendStatic do
end
def call(conn, opts) do
- with false <- invalid_path?(conn.path_info),
+ with false <- api_route?(conn.path_info),
+ false <- invalid_path?(conn.path_info),
frontend_type <- Map.get(opts, :frontend_type, :primary),
path when not is_nil(path) <- file_path("", frontend_type) do
call_static(conn, opts, path)
@@ -52,6 +55,10 @@ defmodule Pleroma.Web.Plugs.FrontendStatic do
defp invalid_path?([h | t], match), do: String.contains?(h, match) or invalid_path?(t)
defp invalid_path?([], _match), do: false
+ defp api_route?([h | _]) when h in @api_routes, do: true
+ defp api_route?([_ | t]), do: api_route?(t)
+ defp api_route?([]), do: false
+
defp call_static(conn, opts, from) do
opts = Map.put(opts, :from, from)
Plug.Static.call(conn, opts)
diff --git a/lib/pleroma/web/plugs/o_auth_scopes_plug.ex b/lib/pleroma/web/plugs/o_auth_scopes_plug.ex
index 0f32f70a6..f017c8bc7 100644
--- a/lib/pleroma/web/plugs/o_auth_scopes_plug.ex
+++ b/lib/pleroma/web/plugs/o_auth_scopes_plug.ex
@@ -6,7 +6,6 @@ defmodule Pleroma.Web.Plugs.OAuthScopesPlug do
import Plug.Conn
import Pleroma.Web.Gettext
- alias Pleroma.Config
alias Pleroma.Helpers.AuthHelper
use Pleroma.Web, :plug
@@ -18,7 +17,6 @@ defmodule Pleroma.Web.Plugs.OAuthScopesPlug do
op = options[:op] || :|
token = assigns[:token]
- scopes = transform_scopes(scopes, options)
matched_scopes = (token && filter_descendants(scopes, token.scopes)) || []
cond do
@@ -57,13 +55,4 @@ defmodule Pleroma.Web.Plugs.OAuthScopesPlug do
end
)
end
-
- @doc "Transforms scopes by applying supported options (e.g. :admin)"
- def transform_scopes(scopes, options) do
- if options[:admin] do
- Config.oauth_admin_scopes(scopes)
- else
- scopes
- end
- end
end
diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex
index 2105d7e9e..de0bd27d7 100644
--- a/lib/pleroma/web/router.ex
+++ b/lib/pleroma/web/router.ex
@@ -37,11 +37,13 @@ defmodule Pleroma.Web.Router do
plug(Pleroma.Web.Plugs.EnsureUserTokenAssignsPlug)
end
- pipeline :expect_authentication do
+ # Note: expects _user_ authentication (user-unbound app-bound tokens don't qualify)
+ pipeline :expect_user_authentication do
plug(Pleroma.Web.Plugs.ExpectAuthenticatedCheckPlug)
end
- pipeline :expect_public_instance_or_authentication do
+ # Note: expects public instance or _user_ authentication (user-unbound tokens don't qualify)
+ pipeline :expect_public_instance_or_user_authentication do
plug(Pleroma.Web.Plugs.ExpectPublicOrAuthenticatedCheckPlug)
end
@@ -66,23 +68,30 @@ defmodule Pleroma.Web.Router do
plug(OpenApiSpex.Plug.PutApiSpec, module: Pleroma.Web.ApiSpec)
end
- pipeline :api do
- plug(:expect_public_instance_or_authentication)
+ pipeline :no_auth_or_privacy_expectations_api do
plug(:base_api)
plug(:after_auth)
plug(Pleroma.Web.Plugs.IdempotencyPlug)
end
+ # Pipeline for app-related endpoints (no user auth checks — app-bound tokens must be supported)
+ pipeline :app_api do
+ plug(:no_auth_or_privacy_expectations_api)
+ end
+
+ pipeline :api do
+ plug(:expect_public_instance_or_user_authentication)
+ plug(:no_auth_or_privacy_expectations_api)
+ end
+
pipeline :authenticated_api do
- plug(:expect_authentication)
- plug(:base_api)
- plug(:after_auth)
+ plug(:expect_user_authentication)
+ plug(:no_auth_or_privacy_expectations_api)
plug(Pleroma.Web.Plugs.EnsureAuthenticatedPlug)
- plug(Pleroma.Web.Plugs.IdempotencyPlug)
end
pipeline :admin_api do
- plug(:expect_authentication)
+ plug(:expect_user_authentication)
plug(:base_api)
plug(Pleroma.Web.Plugs.AdminSecretAuthenticationPlug)
plug(:after_auth)
@@ -131,7 +140,7 @@ defmodule Pleroma.Web.Router do
plug(Pleroma.Web.Plugs.MappedSignatureToIdentityPlug)
end
- scope "/api/pleroma", Pleroma.Web.TwitterAPI do
+ scope "/api/v1/pleroma", Pleroma.Web.TwitterAPI do
pipe_through(:pleroma_api)
get("/password_reset/:token", PasswordController, :reset, as: :reset_password)
@@ -141,12 +150,12 @@ defmodule Pleroma.Web.Router do
get("/healthcheck", UtilController, :healthcheck)
end
- scope "/api/pleroma", Pleroma.Web do
+ scope "/api/v1/pleroma", Pleroma.Web do
pipe_through(:pleroma_api)
post("/uploader_callback/:upload_path", UploaderController, :callback)
end
- scope "/api/pleroma/admin", Pleroma.Web.AdminAPI do
+ scope "/api/v1/pleroma/admin", Pleroma.Web.AdminAPI do
pipe_through(:admin_api)
put("/users/disable_mfa", AdminAPIController, :disable_mfa)
@@ -195,7 +204,7 @@ defmodule Pleroma.Web.Router do
get("/users/:nickname/credentials", AdminAPIController, :show_user_credentials)
patch("/users/:nickname/credentials", AdminAPIController, :update_user_credentials)
- get("/users", UserController, :list)
+ get("/users", UserController, :index)
get("/users/:nickname", UserController, :show)
get("/users/:nickname/statuses", AdminAPIController, :list_user_statuses)
get("/users/:nickname/chats", AdminAPIController, :list_user_chats)
@@ -250,7 +259,7 @@ defmodule Pleroma.Web.Router do
post("/backups", AdminAPIController, :create_backup)
end
- scope "/api/pleroma/emoji", Pleroma.Web.PleromaAPI do
+ scope "/api/v1/pleroma/emoji", Pleroma.Web.PleromaAPI do
scope "/pack" do
pipe_through(:admin_api)
@@ -359,6 +368,12 @@ defmodule Pleroma.Web.Router do
get("/statuses/:id/reactions", EmojiReactionController, :index)
end
+ scope "/api/v0/pleroma", Pleroma.Web.PleromaAPI do
+ pipe_through(:authenticated_api)
+ get("/reports", ReportController, :index)
+ get("/reports/:id", ReportController, :show)
+ end
+
scope "/api/v1/pleroma", Pleroma.Web.PleromaAPI do
scope [] do
pipe_through(:authenticated_api)
@@ -411,6 +426,13 @@ defmodule Pleroma.Web.Router do
get("/federation_status", InstancesController, :show)
end
+ scope "/api/v2/pleroma", Pleroma.Web.PleromaAPI do
+ scope [] do
+ pipe_through(:authenticated_api)
+ get("/chats", ChatController, :index2)
+ end
+ end
+
scope "/api/v1", Pleroma.Web.MastodonAPI do
pipe_through(:authenticated_api)
@@ -432,10 +454,9 @@ defmodule Pleroma.Web.Router do
post("/accounts/:id/mute", AccountController, :mute)
post("/accounts/:id/unmute", AccountController, :unmute)
- get("/apps/verify_credentials", AppController, :verify_credentials)
-
get("/conversations", ConversationController, :index)
post("/conversations/:id/read", ConversationController, :mark_as_read)
+ delete("/conversations/:id", ConversationController, :delete)
get("/domain_blocks", DomainBlockController, :index)
post("/domain_blocks", DomainBlockController, :create)
@@ -525,6 +546,13 @@ defmodule Pleroma.Web.Router do
end
scope "/api/v1", Pleroma.Web.MastodonAPI do
+ pipe_through(:app_api)
+
+ post("/apps", AppController, :create)
+ get("/apps/verify_credentials", AppController, :verify_credentials)
+ end
+
+ scope "/api/v1", Pleroma.Web.MastodonAPI do
pipe_through(:api)
get("/accounts/search", SearchController, :account_search)
@@ -540,8 +568,6 @@ defmodule Pleroma.Web.Router do
get("/instance", InstanceController, :show)
get("/instance/peers", InstanceController, :peers)
- post("/apps", AppController, :create)
-
get("/statuses", StatusController, :index)
get("/statuses/:id", StatusController, :show)
get("/statuses/:id/context", StatusController, :context)
@@ -789,6 +815,7 @@ defmodule Pleroma.Web.Router do
scope "/", Pleroma.Web.Fallback do
get("/registration/:token", RedirectController, :registration_page)
get("/:maybe_nickname_or_id", RedirectController, :redirector_with_meta)
+ match(:*, "/api/pleroma*path", LegacyPleromaApiRerouterPlug, [])
get("/api*path", RedirectController, :api_not_implemented)
get("/*path", RedirectController, :redirector_with_preload)