Merge remote-tracking branch 'remotes/origin/develop' into feature/object-hashtags-rework
# Conflicts: # lib/pleroma/application.ex # lib/pleroma/config.ex
This commit is contained in:
commit
8f88a90ca3
|
@ -371,3 +371,26 @@ docker-release:
|
||||||
- dind
|
- dind
|
||||||
only:
|
only:
|
||||||
- /^release/.*$/@pleroma/pleroma
|
- /^release/.*$/@pleroma/pleroma
|
||||||
|
|
||||||
|
docker-adhoc:
|
||||||
|
stage: docker
|
||||||
|
image: docker:latest
|
||||||
|
cache: {}
|
||||||
|
dependencies: []
|
||||||
|
variables: *docker-variables
|
||||||
|
before_script: *before-docker
|
||||||
|
allow_failure: true
|
||||||
|
script:
|
||||||
|
script:
|
||||||
|
- mkdir -p /root/.docker/cli-plugins
|
||||||
|
- wget "${DOCKER_BUILDX_URL}" -O ~/.docker/cli-plugins/docker-buildx
|
||||||
|
- echo "${DOCKER_BUILDX_HASH} /root/.docker/cli-plugins/docker-buildx" | sha1sum -c
|
||||||
|
- chmod +x ~/.docker/cli-plugins/docker-buildx
|
||||||
|
- docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
|
||||||
|
- docker buildx create --name mbuilder --driver docker-container --use
|
||||||
|
- docker buildx inspect --bootstrap
|
||||||
|
- docker buildx build --platform linux/amd64,linux/arm/v7,linux/arm64/v8 --push --cache-from $IMAGE_TAG_SLUG --build-arg VCS_REF=$CI_VCS_REF --build-arg BUILD_DATE=$CI_JOB_TIMESTAMP -t $IMAGE_TAG -t $IMAGE_TAG_SLUG .
|
||||||
|
tags:
|
||||||
|
- dind
|
||||||
|
only:
|
||||||
|
- /^build-docker/.*$/@pleroma/pleroma
|
|
@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
|
||||||
|
- `:auth, :enforce_oauth_admin_scope_usage` configuration option.
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- **Breaking**: Changed `mix pleroma.user toggle_confirmed` to `mix pleroma.user confirm`
|
- **Breaking**: Changed `mix pleroma.user toggle_confirmed` to `mix pleroma.user confirm`
|
||||||
|
@ -21,6 +25,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
- Provide redirect of external posts from `/notice/:id` to their original URL
|
- Provide redirect of external posts from `/notice/:id` to their original URL
|
||||||
- Admins no longer receive notifications for reports if they are the actor making the report.
|
- Admins no longer receive notifications for reports if they are the actor making the report.
|
||||||
- Improved Mailer configuration setting descriptions for AdminFE.
|
- Improved Mailer configuration setting descriptions for AdminFE.
|
||||||
|
- Updated default avatar to look nicer.
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>API Changes</summary>
|
<summary>API Changes</summary>
|
||||||
|
@ -31,6 +36,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
- **Breaking:** AdminAPI `GET /api/pleroma/admin/users/:nickname_or_id/statuses` changed response format and added the number of total users posts.
|
- **Breaking:** AdminAPI `GET /api/pleroma/admin/users/:nickname_or_id/statuses` changed response format and added the number of total users posts.
|
||||||
- **Breaking:** AdminAPI `GET /api/pleroma/admin/instances/:instance/statuses` changed response format and added the number of total users posts.
|
- **Breaking:** AdminAPI `GET /api/pleroma/admin/instances/:instance/statuses` changed response format and added the number of total users posts.
|
||||||
- Admin API: Reports now ordered by newest
|
- Admin API: Reports now ordered by newest
|
||||||
|
- Pleroma API: `GET /api/v1/pleroma/chats` is deprecated in favor of `GET /api/v2/pleroma/chats`.
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
- Improved hashtag timeline performance (requires a background migration).
|
- Improved hashtag timeline performance (requires a background migration).
|
||||||
|
@ -58,6 +64,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
<details>
|
<details>
|
||||||
<summary>API Changes</summary>
|
<summary>API Changes</summary>
|
||||||
- Admin API: (`GET /api/pleroma/admin/users`) filter users by `unconfirmed` status and `actor_type`.
|
- Admin API: (`GET /api/pleroma/admin/users`) filter users by `unconfirmed` status and `actor_type`.
|
||||||
|
- Pleroma API: `GET /api/v2/pleroma/chats` added. It is exactly like `GET /api/v1/pleroma/chats` except supports pagination.
|
||||||
- Pleroma API: Add `idempotency_key` to the chat message entity that can be used for optimistic message sending.
|
- Pleroma API: Add `idempotency_key` to the chat message entity that can be used for optimistic message sending.
|
||||||
- Pleroma API: (`GET /api/v1/pleroma/federation_status`) Add a way to get a list of unreachable instances.
|
- Pleroma API: (`GET /api/v1/pleroma/federation_status`) Add a way to get a list of unreachable instances.
|
||||||
- Mastodon API: User and conversation mutes can now auto-expire if `expires_in` parameter was given while adding the mute.
|
- Mastodon API: User and conversation mutes can now auto-expire if `expires_in` parameter was given while adding the mute.
|
||||||
|
@ -67,6 +74,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
- Mastodon API: Add monthly active users to `/api/v1/instance` (`pleroma.stats.mau`).
|
- Mastodon API: Add monthly active users to `/api/v1/instance` (`pleroma.stats.mau`).
|
||||||
- Mastodon API: Home, public, hashtag & list timelines accept `only_media`, `remote` & `local` parameters for filtration.
|
- Mastodon API: Home, public, hashtag & list timelines accept `only_media`, `remote` & `local` parameters for filtration.
|
||||||
- Mastodon API: `/api/v1/accounts/:id` & `/api/v1/mutes` endpoints accept `with_relationships` parameter and return filled `pleroma.relationship` field.
|
- Mastodon API: `/api/v1/accounts/:id` & `/api/v1/mutes` endpoints accept `with_relationships` parameter and return filled `pleroma.relationship` field.
|
||||||
|
- Mastodon API: Endpoint to remove a conversation (`DELETE /api/v1/conversations/:id`).
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
7
COPYING
7
COPYING
|
@ -5,6 +5,13 @@ copy of the license file as AGPL-3.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
Files inside docs directory are copyright © 2021 Pleroma Authors
|
||||||
|
<https://pleroma.social/>, and are distributed under the Creative Commons
|
||||||
|
Attribution 4.0 International license, you should have received
|
||||||
|
a copy of the license file as CC-BY-4.0.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
The following files are copyright © 2019 shitposter.club, and are distributed
|
The following files are copyright © 2019 shitposter.club, and are distributed
|
||||||
under the Creative Commons Attribution-ShareAlike 4.0 International license,
|
under the Creative Commons Attribution-ShareAlike 4.0 International license,
|
||||||
you should have received a copy of the license file as CC-BY-SA-4.0.
|
you should have received a copy of the license file as CC-BY-SA-4.0.
|
||||||
|
|
|
@ -611,10 +611,7 @@
|
||||||
base_path: "/oauth",
|
base_path: "/oauth",
|
||||||
providers: ueberauth_providers
|
providers: ueberauth_providers
|
||||||
|
|
||||||
config :pleroma,
|
config :pleroma, :auth, oauth_consumer_strategies: oauth_consumer_strategies
|
||||||
:auth,
|
|
||||||
enforce_oauth_admin_scope_usage: true,
|
|
||||||
oauth_consumer_strategies: oauth_consumer_strategies
|
|
||||||
|
|
||||||
config :pleroma, Pleroma.Emails.Mailer, adapter: Swoosh.Adapters.Sendmail, enabled: false
|
config :pleroma, Pleroma.Emails.Mailer, adapter: Swoosh.Adapters.Sendmail, enabled: false
|
||||||
|
|
||||||
|
|
|
@ -2,13 +2,6 @@
|
||||||
|
|
||||||
Authentication is required and the user must be an admin.
|
Authentication is required and the user must be an admin.
|
||||||
|
|
||||||
Configuration options:
|
|
||||||
|
|
||||||
* `[:auth, :enforce_oauth_admin_scope_usage]` — OAuth admin scope requirement toggle.
|
|
||||||
If `true`, admin actions explicitly demand admin OAuth scope(s) presence in OAuth token (client app must support admin scopes).
|
|
||||||
If `false` and token doesn't have admin scope(s), `is_admin` user flag grants access to admin-specific actions.
|
|
||||||
Note that client app needs to explicitly support admin scopes and request them when obtaining auth token.
|
|
||||||
|
|
||||||
## `GET /api/pleroma/admin/users`
|
## `GET /api/pleroma/admin/users`
|
||||||
|
|
||||||
### List users
|
### List users
|
||||||
|
|
|
@ -97,15 +97,15 @@ def start(_type, _args) do
|
||||||
Pleroma.Stats,
|
Pleroma.Stats,
|
||||||
Pleroma.JobQueueMonitor,
|
Pleroma.JobQueueMonitor,
|
||||||
{Majic.Pool, [name: Pleroma.MajicPool, pool_size: Config.get([:majic_pool, :size], 2)]},
|
{Majic.Pool, [name: Pleroma.MajicPool, pool_size: Config.get([:majic_pool, :size], 2)]},
|
||||||
{Oban, Config.get(Oban)}
|
{Oban, Config.get(Oban)},
|
||||||
|
Pleroma.Web.Endpoint
|
||||||
] ++
|
] ++
|
||||||
task_children(@mix_env) ++
|
task_children(@mix_env) ++
|
||||||
dont_run_in_test(@mix_env) ++
|
dont_run_in_test(@mix_env) ++
|
||||||
chat_child(chat_enabled?()) ++
|
chat_child(chat_enabled?()) ++
|
||||||
[
|
[
|
||||||
Pleroma.Web.Endpoint,
|
Pleroma.Migrators.HashtagsTableMigrator,
|
||||||
Pleroma.Gopher.Server,
|
Pleroma.Gopher.Server
|
||||||
Pleroma.Migrators.HashtagsTableMigrator
|
|
||||||
]
|
]
|
||||||
|
|
||||||
# See http://elixir-lang.org/docs/stable/elixir/Supervisor.html
|
# See http://elixir-lang.org/docs/stable/elixir/Supervisor.html
|
||||||
|
|
|
@ -100,18 +100,6 @@ def oauth_consumer_strategies, do: get([:auth, :oauth_consumer_strategies], [])
|
||||||
|
|
||||||
def oauth_consumer_enabled?, do: oauth_consumer_strategies() != []
|
def oauth_consumer_enabled?, do: oauth_consumer_strategies() != []
|
||||||
|
|
||||||
def enforce_oauth_admin_scope_usage?, do: !!get([:auth, :enforce_oauth_admin_scope_usage])
|
|
||||||
|
|
||||||
def oauth_admin_scopes(scopes) when is_list(scopes) do
|
|
||||||
Enum.flat_map(
|
|
||||||
scopes,
|
|
||||||
fn scope ->
|
|
||||||
["admin:#{scope}"] ++
|
|
||||||
if enforce_oauth_admin_scope_usage?(), do: [], else: [scope]
|
|
||||||
end
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
def feature_enabled?(feature_name) do
|
def feature_enabled?(feature_name) do
|
||||||
get([:features, feature_name]) not in [nil, false, :disabled, :auto]
|
get([:features, feature_name]) not in [nil, false, :disabled, :auto]
|
||||||
end
|
end
|
||||||
|
|
|
@ -61,9 +61,8 @@ def create_or_bump_for(activity, opts \\ []) do
|
||||||
"Create" <- activity.data["type"],
|
"Create" <- activity.data["type"],
|
||||||
%Object{} = object <- Object.normalize(activity, fetch: false),
|
%Object{} = object <- Object.normalize(activity, fetch: false),
|
||||||
true <- object.data["type"] in ["Note", "Question"],
|
true <- object.data["type"] in ["Note", "Question"],
|
||||||
ap_id when is_binary(ap_id) and byte_size(ap_id) > 0 <- object.data["context"] do
|
ap_id when is_binary(ap_id) and byte_size(ap_id) > 0 <- object.data["context"],
|
||||||
{:ok, conversation} = create_for_ap_id(ap_id)
|
{:ok, conversation} <- create_for_ap_id(ap_id) do
|
||||||
|
|
||||||
users = User.get_users_from_set(activity.recipients, local_only: false)
|
users = User.get_users_from_set(activity.recipients, local_only: false)
|
||||||
|
|
||||||
participations =
|
participations =
|
||||||
|
|
|
@ -220,4 +220,8 @@ def unread_conversation_count_for_user(user) do
|
||||||
select: %{count: count(p.id)}
|
select: %{count: count(p.id)}
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def delete(%__MODULE__{} = participation) do
|
||||||
|
Repo.delete(participation)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -11,7 +11,8 @@ defmodule Pleroma.Upload.Filter.Exiftool do
|
||||||
|
|
||||||
@spec filter(Pleroma.Upload.t()) :: {:ok, any()} | {:error, String.t()}
|
@spec filter(Pleroma.Upload.t()) :: {:ok, any()} | {:error, String.t()}
|
||||||
|
|
||||||
# webp is not compatible with exiftool at this time
|
# Formats not compatible with exiftool at this time
|
||||||
|
def filter(%Pleroma.Upload{content_type: "image/heic"}), do: {:ok, :noop}
|
||||||
def filter(%Pleroma.Upload{content_type: "image/webp"}), do: {:ok, :noop}
|
def filter(%Pleroma.Upload{content_type: "image/webp"}), do: {:ok, :noop}
|
||||||
|
|
||||||
def filter(%Pleroma.Upload{tempfile: file, content_type: "image" <> _}) do
|
def filter(%Pleroma.Upload{tempfile: file, content_type: "image" <> _}) do
|
||||||
|
@ -21,8 +22,8 @@ def filter(%Pleroma.Upload{tempfile: file, content_type: "image" <> _}) do
|
||||||
{error, 1} -> {:error, error}
|
{error, 1} -> {:error, error}
|
||||||
end
|
end
|
||||||
rescue
|
rescue
|
||||||
_e in ErlangError ->
|
e in ErlangError ->
|
||||||
{:error, "exiftool command not found"}
|
{:error, "#{__MODULE__}: #{inspect(e)}"}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -44,8 +44,8 @@ def filter(%Pleroma.Upload{tempfile: file, content_type: "image" <> _}) do
|
||||||
Filter.Mogrify.do_filter(file, [Enum.random(@filters)])
|
Filter.Mogrify.do_filter(file, [Enum.random(@filters)])
|
||||||
{:ok, :filtered}
|
{:ok, :filtered}
|
||||||
rescue
|
rescue
|
||||||
_e in ErlangError ->
|
e in ErlangError ->
|
||||||
{:error, "mogrify command not found"}
|
{:error, "#{__MODULE__}: #{inspect(e)}"}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -14,8 +14,8 @@ def filter(%Pleroma.Upload{tempfile: file, content_type: "image" <> _}) do
|
||||||
do_filter(file, Pleroma.Config.get!([__MODULE__, :args]))
|
do_filter(file, Pleroma.Config.get!([__MODULE__, :args]))
|
||||||
{:ok, :filtered}
|
{:ok, :filtered}
|
||||||
rescue
|
rescue
|
||||||
_e in ErlangError ->
|
e in ErlangError ->
|
||||||
{:error, "mogrify command not found"}
|
{:error, "#{__MODULE__}: #{inspect(e)}"}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -25,13 +25,13 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
|
||||||
|
|
||||||
plug(
|
plug(
|
||||||
OAuthScopesPlug,
|
OAuthScopesPlug,
|
||||||
%{scopes: ["read:accounts"], admin: true}
|
%{scopes: ["admin:read:accounts"]}
|
||||||
when action in [:right_get, :show_user_credentials, :create_backup]
|
when action in [:right_get, :show_user_credentials, :create_backup]
|
||||||
)
|
)
|
||||||
|
|
||||||
plug(
|
plug(
|
||||||
OAuthScopesPlug,
|
OAuthScopesPlug,
|
||||||
%{scopes: ["write:accounts"], admin: true}
|
%{scopes: ["admin:write:accounts"]}
|
||||||
when action in [
|
when action in [
|
||||||
:get_password_reset,
|
:get_password_reset,
|
||||||
:force_password_reset,
|
:force_password_reset,
|
||||||
|
@ -48,19 +48,19 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
|
||||||
|
|
||||||
plug(
|
plug(
|
||||||
OAuthScopesPlug,
|
OAuthScopesPlug,
|
||||||
%{scopes: ["read:statuses"], admin: true}
|
%{scopes: ["admin:read:statuses"]}
|
||||||
when action in [:list_user_statuses, :list_instance_statuses]
|
when action in [:list_user_statuses, :list_instance_statuses]
|
||||||
)
|
)
|
||||||
|
|
||||||
plug(
|
plug(
|
||||||
OAuthScopesPlug,
|
OAuthScopesPlug,
|
||||||
%{scopes: ["read:chats"], admin: true}
|
%{scopes: ["admin:read:chats"]}
|
||||||
when action in [:list_user_chats]
|
when action in [:list_user_chats]
|
||||||
)
|
)
|
||||||
|
|
||||||
plug(
|
plug(
|
||||||
OAuthScopesPlug,
|
OAuthScopesPlug,
|
||||||
%{scopes: ["read"], admin: true}
|
%{scopes: ["admin:read"]}
|
||||||
when action in [
|
when action in [
|
||||||
:list_log,
|
:list_log,
|
||||||
:stats,
|
:stats,
|
||||||
|
@ -70,7 +70,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
|
||||||
|
|
||||||
plug(
|
plug(
|
||||||
OAuthScopesPlug,
|
OAuthScopesPlug,
|
||||||
%{scopes: ["write"], admin: true}
|
%{scopes: ["admin:write"]}
|
||||||
when action in [
|
when action in [
|
||||||
:restart,
|
:restart,
|
||||||
:resend_confirmation_email,
|
:resend_confirmation_email,
|
||||||
|
|
|
@ -21,12 +21,12 @@ defmodule Pleroma.Web.AdminAPI.ChatController do
|
||||||
|
|
||||||
plug(
|
plug(
|
||||||
OAuthScopesPlug,
|
OAuthScopesPlug,
|
||||||
%{scopes: ["read:chats"], admin: true} when action in [:show, :messages]
|
%{scopes: ["admin:read:chats"]} when action in [:show, :messages]
|
||||||
)
|
)
|
||||||
|
|
||||||
plug(
|
plug(
|
||||||
OAuthScopesPlug,
|
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)
|
action_fallback(Pleroma.Web.AdminAPI.FallbackController)
|
||||||
|
|
|
@ -10,11 +10,11 @@ defmodule Pleroma.Web.AdminAPI.ConfigController do
|
||||||
alias Pleroma.Web.Plugs.OAuthScopesPlug
|
alias Pleroma.Web.Plugs.OAuthScopesPlug
|
||||||
|
|
||||||
plug(Pleroma.Web.ApiSpec.CastAndValidate)
|
plug(Pleroma.Web.ApiSpec.CastAndValidate)
|
||||||
plug(OAuthScopesPlug, %{scopes: ["write"], admin: true} when action == :update)
|
plug(OAuthScopesPlug, %{scopes: ["admin:write"]} when action == :update)
|
||||||
|
|
||||||
plug(
|
plug(
|
||||||
OAuthScopesPlug,
|
OAuthScopesPlug,
|
||||||
%{scopes: ["read"], admin: true}
|
%{scopes: ["admin:read"]}
|
||||||
when action in [:show, :descriptions]
|
when action in [:show, :descriptions]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,8 @@ defmodule Pleroma.Web.AdminAPI.FrontendController do
|
||||||
alias Pleroma.Web.Plugs.OAuthScopesPlug
|
alias Pleroma.Web.Plugs.OAuthScopesPlug
|
||||||
|
|
||||||
plug(Pleroma.Web.ApiSpec.CastAndValidate)
|
plug(Pleroma.Web.ApiSpec.CastAndValidate)
|
||||||
plug(OAuthScopesPlug, %{scopes: ["write"], admin: true} when action == :install)
|
plug(OAuthScopesPlug, %{scopes: ["admin:write"]} when action == :install)
|
||||||
plug(OAuthScopesPlug, %{scopes: ["read"], admin: true} when action == :index)
|
plug(OAuthScopesPlug, %{scopes: ["admin:read"]} when action == :index)
|
||||||
action_fallback(Pleroma.Web.AdminAPI.FallbackController)
|
action_fallback(Pleroma.Web.AdminAPI.FallbackController)
|
||||||
|
|
||||||
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.Admin.FrontendOperation
|
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.Admin.FrontendOperation
|
||||||
|
|
|
@ -15,8 +15,8 @@ defmodule Pleroma.Web.AdminAPI.InstanceDocumentController do
|
||||||
|
|
||||||
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.Admin.InstanceDocumentOperation
|
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.Admin.InstanceDocumentOperation
|
||||||
|
|
||||||
plug(OAuthScopesPlug, %{scopes: ["read"], admin: true} when action == :show)
|
plug(OAuthScopesPlug, %{scopes: ["admin:read"]} when action == :show)
|
||||||
plug(OAuthScopesPlug, %{scopes: ["write"], admin: true} when action in [:update, :delete])
|
plug(OAuthScopesPlug, %{scopes: ["admin:write"]} when action in [:update, :delete])
|
||||||
|
|
||||||
def show(conn, %{name: document_name}) do
|
def show(conn, %{name: document_name}) do
|
||||||
with {:ok, url} <- InstanceDocument.get(document_name),
|
with {:ok, url} <- InstanceDocument.get(document_name),
|
||||||
|
|
|
@ -14,11 +14,11 @@ defmodule Pleroma.Web.AdminAPI.InviteController do
|
||||||
require Logger
|
require Logger
|
||||||
|
|
||||||
plug(Pleroma.Web.ApiSpec.CastAndValidate)
|
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(
|
plug(
|
||||||
OAuthScopesPlug,
|
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)
|
action_fallback(Pleroma.Web.AdminAPI.FallbackController)
|
||||||
|
|
|
@ -15,12 +15,12 @@ defmodule Pleroma.Web.AdminAPI.MediaProxyCacheController do
|
||||||
|
|
||||||
plug(
|
plug(
|
||||||
OAuthScopesPlug,
|
OAuthScopesPlug,
|
||||||
%{scopes: ["read:media_proxy_caches"], admin: true} when action in [:index]
|
%{scopes: ["admin:read:media_proxy_caches"]} when action in [:index]
|
||||||
)
|
)
|
||||||
|
|
||||||
plug(
|
plug(
|
||||||
OAuthScopesPlug,
|
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)
|
action_fallback(Pleroma.Web.AdminAPI.FallbackController)
|
||||||
|
|
|
@ -17,7 +17,7 @@ defmodule Pleroma.Web.AdminAPI.OAuthAppController do
|
||||||
|
|
||||||
plug(
|
plug(
|
||||||
OAuthScopesPlug,
|
OAuthScopesPlug,
|
||||||
%{scopes: ["write"], admin: true}
|
%{scopes: ["admin:write"]}
|
||||||
when action in [:create, :index, :update, :delete]
|
when action in [:create, :index, :update, :delete]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -15,11 +15,11 @@ defmodule Pleroma.Web.AdminAPI.RelayController do
|
||||||
|
|
||||||
plug(
|
plug(
|
||||||
OAuthScopesPlug,
|
OAuthScopesPlug,
|
||||||
%{scopes: ["write:follows"], admin: true}
|
%{scopes: ["admin:write:follows"]}
|
||||||
when action in [:follow, :unfollow]
|
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)
|
action_fallback(Pleroma.Web.AdminAPI.FallbackController)
|
||||||
|
|
||||||
|
|
|
@ -19,11 +19,11 @@ defmodule Pleroma.Web.AdminAPI.ReportController do
|
||||||
require Logger
|
require Logger
|
||||||
|
|
||||||
plug(Pleroma.Web.ApiSpec.CastAndValidate)
|
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(
|
plug(
|
||||||
OAuthScopesPlug,
|
OAuthScopesPlug,
|
||||||
%{scopes: ["write:reports"], admin: true}
|
%{scopes: ["admin:write:reports"]}
|
||||||
when action in [:update, :notes_create, :notes_delete]
|
when action in [:update, :notes_create, :notes_delete]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -15,11 +15,11 @@ defmodule Pleroma.Web.AdminAPI.StatusController do
|
||||||
require Logger
|
require Logger
|
||||||
|
|
||||||
plug(Pleroma.Web.ApiSpec.CastAndValidate)
|
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(
|
plug(
|
||||||
OAuthScopesPlug,
|
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)
|
action_fallback(Pleroma.Web.AdminAPI.FallbackController)
|
||||||
|
|
|
@ -21,13 +21,13 @@ defmodule Pleroma.Web.AdminAPI.UserController do
|
||||||
|
|
||||||
plug(
|
plug(
|
||||||
OAuthScopesPlug,
|
OAuthScopesPlug,
|
||||||
%{scopes: ["read:accounts"], admin: true}
|
%{scopes: ["admin:read:accounts"]}
|
||||||
when action in [:list, :show]
|
when action in [:list, :show]
|
||||||
)
|
)
|
||||||
|
|
||||||
plug(
|
plug(
|
||||||
OAuthScopesPlug,
|
OAuthScopesPlug,
|
||||||
%{scopes: ["write:accounts"], admin: true}
|
%{scopes: ["admin:write:accounts"]}
|
||||||
when action in [
|
when action in [
|
||||||
:delete,
|
:delete,
|
||||||
:create,
|
:create,
|
||||||
|
@ -40,7 +40,7 @@ defmodule Pleroma.Web.AdminAPI.UserController do
|
||||||
|
|
||||||
plug(
|
plug(
|
||||||
OAuthScopesPlug,
|
OAuthScopesPlug,
|
||||||
%{scopes: ["write:follows"], admin: true}
|
%{scopes: ["admin:write:follows"]}
|
||||||
when action in [:follow, :unfollow]
|
when action in [:follow, :unfollow]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -85,7 +85,7 @@ def spec(opts \\ []) do
|
||||||
"name" => "Administration",
|
"name" => "Administration",
|
||||||
"tags" => [
|
"tags" => [
|
||||||
"Chat administration",
|
"Chat administration",
|
||||||
"Emoji packs",
|
"Emoji pack administration",
|
||||||
"Frontend managment",
|
"Frontend managment",
|
||||||
"Instance configuration",
|
"Instance configuration",
|
||||||
"Instance documents",
|
"Instance documents",
|
||||||
|
@ -127,7 +127,7 @@ def spec(opts \\ []) do
|
||||||
"Status actions"
|
"Status actions"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
%{"name" => "Miscellaneous", "tags" => ["Reports", "Suggestions"]}
|
%{"name" => "Miscellaneous", "tags" => ["Emoji packs", "Reports", "Suggestions"]}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ def delete_message_operation do
|
||||||
},
|
},
|
||||||
security: [
|
security: [
|
||||||
%{
|
%{
|
||||||
"oAuth" => ["write:chats"]
|
"oAuth" => ["admin:write:chats"]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ def messages_operation do
|
||||||
},
|
},
|
||||||
security: [
|
security: [
|
||||||
%{
|
%{
|
||||||
"oAuth" => ["read:chats"]
|
"oAuth" => ["admin:read:chats"]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -88,7 +88,7 @@ def show_operation do
|
||||||
},
|
},
|
||||||
security: [
|
security: [
|
||||||
%{
|
%{
|
||||||
"oAuth" => ["read"]
|
"oAuth" => ["admin:read"]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ def show_operation do
|
||||||
)
|
)
|
||||||
| admin_api_params()
|
| admin_api_params()
|
||||||
],
|
],
|
||||||
security: [%{"oAuth" => ["read"]}],
|
security: [%{"oAuth" => ["admin:read"]}],
|
||||||
responses: %{
|
responses: %{
|
||||||
200 => Operation.response("Config", "application/json", config_response()),
|
200 => Operation.response("Config", "application/json", config_response()),
|
||||||
400 => Operation.response("Bad Request", "application/json", ApiError)
|
400 => Operation.response("Bad Request", "application/json", ApiError)
|
||||||
|
@ -41,7 +41,7 @@ def update_operation do
|
||||||
tags: ["Instance configuration"],
|
tags: ["Instance configuration"],
|
||||||
summary: "Update instance configuration",
|
summary: "Update instance configuration",
|
||||||
operationId: "AdminAPI.ConfigController.update",
|
operationId: "AdminAPI.ConfigController.update",
|
||||||
security: [%{"oAuth" => ["write"]}],
|
security: [%{"oAuth" => ["admin:write"]}],
|
||||||
parameters: admin_api_params(),
|
parameters: admin_api_params(),
|
||||||
requestBody:
|
requestBody:
|
||||||
request_body("Parameters", %Schema{
|
request_body("Parameters", %Schema{
|
||||||
|
@ -74,7 +74,7 @@ def descriptions_operation do
|
||||||
tags: ["Instance configuration"],
|
tags: ["Instance configuration"],
|
||||||
summary: "Retrieve config description",
|
summary: "Retrieve config description",
|
||||||
operationId: "AdminAPI.ConfigController.descriptions",
|
operationId: "AdminAPI.ConfigController.descriptions",
|
||||||
security: [%{"oAuth" => ["read"]}],
|
security: [%{"oAuth" => ["admin:read"]}],
|
||||||
parameters: admin_api_params(),
|
parameters: admin_api_params(),
|
||||||
responses: %{
|
responses: %{
|
||||||
200 =>
|
200 =>
|
||||||
|
|
|
@ -19,7 +19,7 @@ def index_operation do
|
||||||
tags: ["Frontend managment"],
|
tags: ["Frontend managment"],
|
||||||
summary: "Retrieve a list of available frontends",
|
summary: "Retrieve a list of available frontends",
|
||||||
operationId: "AdminAPI.FrontendController.index",
|
operationId: "AdminAPI.FrontendController.index",
|
||||||
security: [%{"oAuth" => ["read"]}],
|
security: [%{"oAuth" => ["admin:read"]}],
|
||||||
responses: %{
|
responses: %{
|
||||||
200 => Operation.response("Response", "application/json", list_of_frontends()),
|
200 => Operation.response("Response", "application/json", list_of_frontends()),
|
||||||
403 => Operation.response("Forbidden", "application/json", ApiError)
|
403 => Operation.response("Forbidden", "application/json", ApiError)
|
||||||
|
@ -32,7 +32,7 @@ def install_operation do
|
||||||
tags: ["Frontend managment"],
|
tags: ["Frontend managment"],
|
||||||
summary: "Install a frontend",
|
summary: "Install a frontend",
|
||||||
operationId: "AdminAPI.FrontendController.install",
|
operationId: "AdminAPI.FrontendController.install",
|
||||||
security: [%{"oAuth" => ["read"]}],
|
security: [%{"oAuth" => ["admin:read"]}],
|
||||||
requestBody: request_body("Parameters", install_request(), required: true),
|
requestBody: request_body("Parameters", install_request(), required: true),
|
||||||
responses: %{
|
responses: %{
|
||||||
200 => Operation.response("Response", "application/json", list_of_frontends()),
|
200 => Operation.response("Response", "application/json", list_of_frontends()),
|
||||||
|
|
|
@ -18,7 +18,7 @@ def show_operation do
|
||||||
tags: ["Instance documents"],
|
tags: ["Instance documents"],
|
||||||
summary: "Retrieve an instance document",
|
summary: "Retrieve an instance document",
|
||||||
operationId: "AdminAPI.InstanceDocumentController.show",
|
operationId: "AdminAPI.InstanceDocumentController.show",
|
||||||
security: [%{"oAuth" => ["read"]}],
|
security: [%{"oAuth" => ["admin:read"]}],
|
||||||
parameters: [
|
parameters: [
|
||||||
Operation.parameter(:name, :path, %Schema{type: :string}, "The document name",
|
Operation.parameter(:name, :path, %Schema{type: :string}, "The document name",
|
||||||
required: true
|
required: true
|
||||||
|
@ -39,7 +39,7 @@ def update_operation do
|
||||||
tags: ["Instance documents"],
|
tags: ["Instance documents"],
|
||||||
summary: "Update an instance document",
|
summary: "Update an instance document",
|
||||||
operationId: "AdminAPI.InstanceDocumentController.update",
|
operationId: "AdminAPI.InstanceDocumentController.update",
|
||||||
security: [%{"oAuth" => ["write"]}],
|
security: [%{"oAuth" => ["admin:write"]}],
|
||||||
requestBody: Helpers.request_body("Parameters", update_request()),
|
requestBody: Helpers.request_body("Parameters", update_request()),
|
||||||
parameters: [
|
parameters: [
|
||||||
Operation.parameter(:name, :path, %Schema{type: :string}, "The document name",
|
Operation.parameter(:name, :path, %Schema{type: :string}, "The document name",
|
||||||
|
@ -77,7 +77,7 @@ def delete_operation do
|
||||||
tags: ["Instance documents"],
|
tags: ["Instance documents"],
|
||||||
summary: "Delete an instance document",
|
summary: "Delete an instance document",
|
||||||
operationId: "AdminAPI.InstanceDocumentController.delete",
|
operationId: "AdminAPI.InstanceDocumentController.delete",
|
||||||
security: [%{"oAuth" => ["write"]}],
|
security: [%{"oAuth" => ["admin:write"]}],
|
||||||
parameters: [
|
parameters: [
|
||||||
Operation.parameter(:name, :path, %Schema{type: :string}, "The document name",
|
Operation.parameter(:name, :path, %Schema{type: :string}, "The document name",
|
||||||
required: true
|
required: true
|
||||||
|
|
|
@ -19,7 +19,7 @@ def index_operation do
|
||||||
tags: ["Invites"],
|
tags: ["Invites"],
|
||||||
summary: "Get a list of generated invites",
|
summary: "Get a list of generated invites",
|
||||||
operationId: "AdminAPI.InviteController.index",
|
operationId: "AdminAPI.InviteController.index",
|
||||||
security: [%{"oAuth" => ["read:invites"]}],
|
security: [%{"oAuth" => ["admin:read:invites"]}],
|
||||||
parameters: admin_api_params(),
|
parameters: admin_api_params(),
|
||||||
responses: %{
|
responses: %{
|
||||||
200 =>
|
200 =>
|
||||||
|
@ -51,7 +51,7 @@ def create_operation do
|
||||||
tags: ["Invites"],
|
tags: ["Invites"],
|
||||||
summary: "Create an account registration invite token",
|
summary: "Create an account registration invite token",
|
||||||
operationId: "AdminAPI.InviteController.create",
|
operationId: "AdminAPI.InviteController.create",
|
||||||
security: [%{"oAuth" => ["write:invites"]}],
|
security: [%{"oAuth" => ["admin:write:invites"]}],
|
||||||
parameters: admin_api_params(),
|
parameters: admin_api_params(),
|
||||||
requestBody:
|
requestBody:
|
||||||
request_body("Parameters", %Schema{
|
request_body("Parameters", %Schema{
|
||||||
|
@ -72,7 +72,7 @@ def revoke_operation do
|
||||||
tags: ["Invites"],
|
tags: ["Invites"],
|
||||||
summary: "Revoke invite by token",
|
summary: "Revoke invite by token",
|
||||||
operationId: "AdminAPI.InviteController.revoke",
|
operationId: "AdminAPI.InviteController.revoke",
|
||||||
security: [%{"oAuth" => ["write:invites"]}],
|
security: [%{"oAuth" => ["admin:write:invites"]}],
|
||||||
parameters: admin_api_params(),
|
parameters: admin_api_params(),
|
||||||
requestBody:
|
requestBody:
|
||||||
request_body(
|
request_body(
|
||||||
|
@ -99,7 +99,7 @@ def email_operation do
|
||||||
tags: ["Invites"],
|
tags: ["Invites"],
|
||||||
summary: "Sends registration invite via email",
|
summary: "Sends registration invite via email",
|
||||||
operationId: "AdminAPI.InviteController.email",
|
operationId: "AdminAPI.InviteController.email",
|
||||||
security: [%{"oAuth" => ["write:invites"]}],
|
security: [%{"oAuth" => ["admin:write:invites"]}],
|
||||||
parameters: admin_api_params(),
|
parameters: admin_api_params(),
|
||||||
requestBody:
|
requestBody:
|
||||||
request_body(
|
request_body(
|
||||||
|
|
|
@ -19,7 +19,7 @@ def index_operation do
|
||||||
tags: ["MediaProxy cache"],
|
tags: ["MediaProxy cache"],
|
||||||
summary: "Retrieve a list of banned MediaProxy URLs",
|
summary: "Retrieve a list of banned MediaProxy URLs",
|
||||||
operationId: "AdminAPI.MediaProxyCacheController.index",
|
operationId: "AdminAPI.MediaProxyCacheController.index",
|
||||||
security: [%{"oAuth" => ["read:media_proxy_caches"]}],
|
security: [%{"oAuth" => ["admin:read:media_proxy_caches"]}],
|
||||||
parameters: [
|
parameters: [
|
||||||
Operation.parameter(
|
Operation.parameter(
|
||||||
:query,
|
:query,
|
||||||
|
@ -71,7 +71,7 @@ def delete_operation do
|
||||||
tags: ["MediaProxy cache"],
|
tags: ["MediaProxy cache"],
|
||||||
summary: "Remove a banned MediaProxy URL",
|
summary: "Remove a banned MediaProxy URL",
|
||||||
operationId: "AdminAPI.MediaProxyCacheController.delete",
|
operationId: "AdminAPI.MediaProxyCacheController.delete",
|
||||||
security: [%{"oAuth" => ["write:media_proxy_caches"]}],
|
security: [%{"oAuth" => ["admin:write:media_proxy_caches"]}],
|
||||||
parameters: admin_api_params(),
|
parameters: admin_api_params(),
|
||||||
requestBody:
|
requestBody:
|
||||||
request_body(
|
request_body(
|
||||||
|
@ -97,7 +97,7 @@ def purge_operation do
|
||||||
tags: ["MediaProxy cache"],
|
tags: ["MediaProxy cache"],
|
||||||
summary: "Purge a URL from MediaProxy cache and optionally ban it",
|
summary: "Purge a URL from MediaProxy cache and optionally ban it",
|
||||||
operationId: "AdminAPI.MediaProxyCacheController.purge",
|
operationId: "AdminAPI.MediaProxyCacheController.purge",
|
||||||
security: [%{"oAuth" => ["write:media_proxy_caches"]}],
|
security: [%{"oAuth" => ["admin:write:media_proxy_caches"]}],
|
||||||
parameters: admin_api_params(),
|
parameters: admin_api_params(),
|
||||||
requestBody:
|
requestBody:
|
||||||
request_body(
|
request_body(
|
||||||
|
|
|
@ -19,7 +19,7 @@ def index_operation do
|
||||||
summary: "Retrieve a list of OAuth applications",
|
summary: "Retrieve a list of OAuth applications",
|
||||||
tags: ["OAuth application managment"],
|
tags: ["OAuth application managment"],
|
||||||
operationId: "AdminAPI.OAuthAppController.index",
|
operationId: "AdminAPI.OAuthAppController.index",
|
||||||
security: [%{"oAuth" => ["write"]}],
|
security: [%{"oAuth" => ["admin:write"]}],
|
||||||
parameters: [
|
parameters: [
|
||||||
Operation.parameter(:name, :query, %Schema{type: :string}, "App name"),
|
Operation.parameter(:name, :query, %Schema{type: :string}, "App name"),
|
||||||
Operation.parameter(:client_id, :query, %Schema{type: :string}, "Client ID"),
|
Operation.parameter(:client_id, :query, %Schema{type: :string}, "Client ID"),
|
||||||
|
@ -74,7 +74,7 @@ def create_operation do
|
||||||
operationId: "AdminAPI.OAuthAppController.create",
|
operationId: "AdminAPI.OAuthAppController.create",
|
||||||
requestBody: request_body("Parameters", create_request()),
|
requestBody: request_body("Parameters", create_request()),
|
||||||
parameters: admin_api_params(),
|
parameters: admin_api_params(),
|
||||||
security: [%{"oAuth" => ["write"]}],
|
security: [%{"oAuth" => ["admin:write"]}],
|
||||||
responses: %{
|
responses: %{
|
||||||
200 => Operation.response("App", "application/json", oauth_app()),
|
200 => Operation.response("App", "application/json", oauth_app()),
|
||||||
400 => Operation.response("Bad Request", "application/json", ApiError)
|
400 => Operation.response("Bad Request", "application/json", ApiError)
|
||||||
|
@ -88,7 +88,7 @@ def update_operation do
|
||||||
summary: "Update OAuth application",
|
summary: "Update OAuth application",
|
||||||
operationId: "AdminAPI.OAuthAppController.update",
|
operationId: "AdminAPI.OAuthAppController.update",
|
||||||
parameters: [id_param() | admin_api_params()],
|
parameters: [id_param() | admin_api_params()],
|
||||||
security: [%{"oAuth" => ["write"]}],
|
security: [%{"oAuth" => ["admin:write"]}],
|
||||||
requestBody: request_body("Parameters", update_request()),
|
requestBody: request_body("Parameters", update_request()),
|
||||||
responses: %{
|
responses: %{
|
||||||
200 => Operation.response("App", "application/json", oauth_app()),
|
200 => Operation.response("App", "application/json", oauth_app()),
|
||||||
|
@ -106,7 +106,7 @@ def delete_operation do
|
||||||
summary: "Delete OAuth application",
|
summary: "Delete OAuth application",
|
||||||
operationId: "AdminAPI.OAuthAppController.delete",
|
operationId: "AdminAPI.OAuthAppController.delete",
|
||||||
parameters: [id_param() | admin_api_params()],
|
parameters: [id_param() | admin_api_params()],
|
||||||
security: [%{"oAuth" => ["write"]}],
|
security: [%{"oAuth" => ["admin:write"]}],
|
||||||
responses: %{
|
responses: %{
|
||||||
204 => no_content_response(),
|
204 => no_content_response(),
|
||||||
400 => no_content_response()
|
400 => no_content_response()
|
||||||
|
|
|
@ -18,7 +18,7 @@ def index_operation do
|
||||||
tags: ["Relays"],
|
tags: ["Relays"],
|
||||||
summary: "Retrieve a list of relays",
|
summary: "Retrieve a list of relays",
|
||||||
operationId: "AdminAPI.RelayController.index",
|
operationId: "AdminAPI.RelayController.index",
|
||||||
security: [%{"oAuth" => ["read"]}],
|
security: [%{"oAuth" => ["admin:read"]}],
|
||||||
parameters: admin_api_params(),
|
parameters: admin_api_params(),
|
||||||
responses: %{
|
responses: %{
|
||||||
200 =>
|
200 =>
|
||||||
|
@ -40,7 +40,7 @@ def follow_operation do
|
||||||
tags: ["Relays"],
|
tags: ["Relays"],
|
||||||
summary: "Follow a relay",
|
summary: "Follow a relay",
|
||||||
operationId: "AdminAPI.RelayController.follow",
|
operationId: "AdminAPI.RelayController.follow",
|
||||||
security: [%{"oAuth" => ["write:follows"]}],
|
security: [%{"oAuth" => ["admin:write:follows"]}],
|
||||||
parameters: admin_api_params(),
|
parameters: admin_api_params(),
|
||||||
requestBody: request_body("Parameters", relay_url()),
|
requestBody: request_body("Parameters", relay_url()),
|
||||||
responses: %{
|
responses: %{
|
||||||
|
@ -54,7 +54,7 @@ def unfollow_operation do
|
||||||
tags: ["Relays"],
|
tags: ["Relays"],
|
||||||
summary: "Unfollow a relay",
|
summary: "Unfollow a relay",
|
||||||
operationId: "AdminAPI.RelayController.unfollow",
|
operationId: "AdminAPI.RelayController.unfollow",
|
||||||
security: [%{"oAuth" => ["write:follows"]}],
|
security: [%{"oAuth" => ["admin:write:follows"]}],
|
||||||
parameters: admin_api_params(),
|
parameters: admin_api_params(),
|
||||||
requestBody: request_body("Parameters", relay_unfollow()),
|
requestBody: request_body("Parameters", relay_unfollow()),
|
||||||
responses: %{
|
responses: %{
|
||||||
|
|
|
@ -22,7 +22,7 @@ def index_operation do
|
||||||
tags: ["Report managment"],
|
tags: ["Report managment"],
|
||||||
summary: "Retrieve a list of reports",
|
summary: "Retrieve a list of reports",
|
||||||
operationId: "AdminAPI.ReportController.index",
|
operationId: "AdminAPI.ReportController.index",
|
||||||
security: [%{"oAuth" => ["read:reports"]}],
|
security: [%{"oAuth" => ["admin:read:reports"]}],
|
||||||
parameters: [
|
parameters: [
|
||||||
Operation.parameter(
|
Operation.parameter(
|
||||||
:state,
|
:state,
|
||||||
|
@ -73,7 +73,7 @@ def show_operation do
|
||||||
summary: "Retrieve a report",
|
summary: "Retrieve a report",
|
||||||
operationId: "AdminAPI.ReportController.show",
|
operationId: "AdminAPI.ReportController.show",
|
||||||
parameters: [id_param() | admin_api_params()],
|
parameters: [id_param() | admin_api_params()],
|
||||||
security: [%{"oAuth" => ["read:reports"]}],
|
security: [%{"oAuth" => ["admin:read:reports"]}],
|
||||||
responses: %{
|
responses: %{
|
||||||
200 => Operation.response("Report", "application/json", report()),
|
200 => Operation.response("Report", "application/json", report()),
|
||||||
404 => Operation.response("Not Found", "application/json", ApiError)
|
404 => Operation.response("Not Found", "application/json", ApiError)
|
||||||
|
@ -86,7 +86,7 @@ def update_operation do
|
||||||
tags: ["Report managment"],
|
tags: ["Report managment"],
|
||||||
summary: "Change state of specified reports",
|
summary: "Change state of specified reports",
|
||||||
operationId: "AdminAPI.ReportController.update",
|
operationId: "AdminAPI.ReportController.update",
|
||||||
security: [%{"oAuth" => ["write:reports"]}],
|
security: [%{"oAuth" => ["admin:write:reports"]}],
|
||||||
parameters: admin_api_params(),
|
parameters: admin_api_params(),
|
||||||
requestBody: request_body("Parameters", update_request(), required: true),
|
requestBody: request_body("Parameters", update_request(), required: true),
|
||||||
responses: %{
|
responses: %{
|
||||||
|
@ -110,7 +110,7 @@ def notes_create_operation do
|
||||||
content: %Schema{type: :string, description: "The message"}
|
content: %Schema{type: :string, description: "The message"}
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
security: [%{"oAuth" => ["write:reports"]}],
|
security: [%{"oAuth" => ["admin:write:reports"]}],
|
||||||
responses: %{
|
responses: %{
|
||||||
204 => no_content_response(),
|
204 => no_content_response(),
|
||||||
404 => Operation.response("Not Found", "application/json", ApiError)
|
404 => Operation.response("Not Found", "application/json", ApiError)
|
||||||
|
@ -128,7 +128,7 @@ def notes_delete_operation do
|
||||||
Operation.parameter(:id, :path, :string, "Note ID")
|
Operation.parameter(:id, :path, :string, "Note ID")
|
||||||
| admin_api_params()
|
| admin_api_params()
|
||||||
],
|
],
|
||||||
security: [%{"oAuth" => ["write:reports"]}],
|
security: [%{"oAuth" => ["admin:write:reports"]}],
|
||||||
responses: %{
|
responses: %{
|
||||||
204 => no_content_response(),
|
204 => no_content_response(),
|
||||||
404 => Operation.response("Not Found", "application/json", ApiError)
|
404 => Operation.response("Not Found", "application/json", ApiError)
|
||||||
|
|
|
@ -24,7 +24,7 @@ def index_operation do
|
||||||
tags: ["Status administration"],
|
tags: ["Status administration"],
|
||||||
operationId: "AdminAPI.StatusController.index",
|
operationId: "AdminAPI.StatusController.index",
|
||||||
summary: "Get all statuses",
|
summary: "Get all statuses",
|
||||||
security: [%{"oAuth" => ["read:statuses"]}],
|
security: [%{"oAuth" => ["admin:read:statuses"]}],
|
||||||
parameters: [
|
parameters: [
|
||||||
Operation.parameter(
|
Operation.parameter(
|
||||||
:godmode,
|
:godmode,
|
||||||
|
@ -74,7 +74,7 @@ def show_operation do
|
||||||
summary: "Get status",
|
summary: "Get status",
|
||||||
operationId: "AdminAPI.StatusController.show",
|
operationId: "AdminAPI.StatusController.show",
|
||||||
parameters: [id_param() | admin_api_params()],
|
parameters: [id_param() | admin_api_params()],
|
||||||
security: [%{"oAuth" => ["read:statuses"]}],
|
security: [%{"oAuth" => ["admin:read:statuses"]}],
|
||||||
responses: %{
|
responses: %{
|
||||||
200 => Operation.response("Status", "application/json", status()),
|
200 => Operation.response("Status", "application/json", status()),
|
||||||
404 => Operation.response("Not Found", "application/json", ApiError)
|
404 => Operation.response("Not Found", "application/json", ApiError)
|
||||||
|
@ -88,7 +88,7 @@ def update_operation do
|
||||||
summary: "Change the scope of a status",
|
summary: "Change the scope of a status",
|
||||||
operationId: "AdminAPI.StatusController.update",
|
operationId: "AdminAPI.StatusController.update",
|
||||||
parameters: [id_param() | admin_api_params()],
|
parameters: [id_param() | admin_api_params()],
|
||||||
security: [%{"oAuth" => ["write:statuses"]}],
|
security: [%{"oAuth" => ["admin:write:statuses"]}],
|
||||||
requestBody: request_body("Parameters", update_request(), required: true),
|
requestBody: request_body("Parameters", update_request(), required: true),
|
||||||
responses: %{
|
responses: %{
|
||||||
200 => Operation.response("Status", "application/json", Status),
|
200 => Operation.response("Status", "application/json", Status),
|
||||||
|
@ -103,7 +103,7 @@ def delete_operation do
|
||||||
summary: "Delete status",
|
summary: "Delete status",
|
||||||
operationId: "AdminAPI.StatusController.delete",
|
operationId: "AdminAPI.StatusController.delete",
|
||||||
parameters: [id_param() | admin_api_params()],
|
parameters: [id_param() | admin_api_params()],
|
||||||
security: [%{"oAuth" => ["write:statuses"]}],
|
security: [%{"oAuth" => ["admin:write:statuses"]}],
|
||||||
responses: %{
|
responses: %{
|
||||||
200 => empty_object_response(),
|
200 => empty_object_response(),
|
||||||
404 => Operation.response("Not Found", "application/json", ApiError)
|
404 => Operation.response("Not Found", "application/json", ApiError)
|
||||||
|
|
|
@ -131,8 +131,30 @@ def create_operation do
|
||||||
def index_operation do
|
def index_operation do
|
||||||
%Operation{
|
%Operation{
|
||||||
tags: ["Chats"],
|
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",
|
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: [
|
parameters: [
|
||||||
Operation.parameter(:with_muted, :query, BooleanLike, "Include chats from muted users")
|
Operation.parameter(:with_muted, :query, BooleanLike, "Include chats from muted users")
|
||||||
| pagination_params()
|
| pagination_params()
|
||||||
|
|
|
@ -46,16 +46,31 @@ def mark_as_read_operation do
|
||||||
tags: ["Conversations"],
|
tags: ["Conversations"],
|
||||||
summary: "Mark conversation as read",
|
summary: "Mark conversation as read",
|
||||||
operationId: "ConversationController.mark_as_read",
|
operationId: "ConversationController.mark_as_read",
|
||||||
parameters: [
|
parameters: [id_param()],
|
||||||
Operation.parameter(:id, :path, :string, "Conversation ID",
|
|
||||||
example: "123",
|
|
||||||
required: true
|
|
||||||
)
|
|
||||||
],
|
|
||||||
security: [%{"oAuth" => ["write:conversations"]}],
|
security: [%{"oAuth" => ["write:conversations"]}],
|
||||||
responses: %{
|
responses: %{
|
||||||
200 => Operation.response("Conversation", "application/json", Conversation)
|
200 => Operation.response("Conversation", "application/json", Conversation)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end
|
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
|
end
|
||||||
|
|
|
@ -16,10 +16,10 @@ def open_api_operation(action) do
|
||||||
|
|
||||||
def create_operation do
|
def create_operation do
|
||||||
%Operation{
|
%Operation{
|
||||||
tags: ["Emoji packs"],
|
tags: ["Emoji pack administration"],
|
||||||
summary: "Add new file to the pack",
|
summary: "Add new file to the pack",
|
||||||
operationId: "PleromaAPI.EmojiPackController.add_file",
|
operationId: "PleromaAPI.EmojiPackController.add_file",
|
||||||
security: [%{"oAuth" => ["write"]}],
|
security: [%{"oAuth" => ["admin:write"]}],
|
||||||
requestBody: request_body("Parameters", create_request(), required: true),
|
requestBody: request_body("Parameters", create_request(), required: true),
|
||||||
parameters: [name_param()],
|
parameters: [name_param()],
|
||||||
responses: %{
|
responses: %{
|
||||||
|
@ -62,10 +62,10 @@ defp create_request do
|
||||||
|
|
||||||
def update_operation do
|
def update_operation do
|
||||||
%Operation{
|
%Operation{
|
||||||
tags: ["Emoji packs"],
|
tags: ["Emoji pack administration"],
|
||||||
summary: "Add new file to the pack",
|
summary: "Add new file to the pack",
|
||||||
operationId: "PleromaAPI.EmojiPackController.update_file",
|
operationId: "PleromaAPI.EmojiPackController.update_file",
|
||||||
security: [%{"oAuth" => ["write"]}],
|
security: [%{"oAuth" => ["admin:write"]}],
|
||||||
requestBody: request_body("Parameters", update_request(), required: true),
|
requestBody: request_body("Parameters", update_request(), required: true),
|
||||||
parameters: [name_param()],
|
parameters: [name_param()],
|
||||||
responses: %{
|
responses: %{
|
||||||
|
@ -106,10 +106,10 @@ defp update_request do
|
||||||
|
|
||||||
def delete_operation do
|
def delete_operation do
|
||||||
%Operation{
|
%Operation{
|
||||||
tags: ["Emoji packs"],
|
tags: ["Emoji pack administration"],
|
||||||
summary: "Delete emoji file from pack",
|
summary: "Delete emoji file from pack",
|
||||||
operationId: "PleromaAPI.EmojiPackController.delete_file",
|
operationId: "PleromaAPI.EmojiPackController.delete_file",
|
||||||
security: [%{"oAuth" => ["write"]}],
|
security: [%{"oAuth" => ["admin:write"]}],
|
||||||
parameters: [
|
parameters: [
|
||||||
name_param(),
|
name_param(),
|
||||||
Operation.parameter(:shortcode, :query, :string, "File shortcode",
|
Operation.parameter(:shortcode, :query, :string, "File shortcode",
|
||||||
|
|
|
@ -16,9 +16,9 @@ def open_api_operation(action) do
|
||||||
|
|
||||||
def remote_operation do
|
def remote_operation do
|
||||||
%Operation{
|
%Operation{
|
||||||
tags: ["Emoji packs"],
|
tags: ["Emoji pack administration"],
|
||||||
summary: "Make request to another instance for emoji packs list",
|
summary: "Make request to another instance for emoji packs list",
|
||||||
security: [%{"oAuth" => ["write"]}],
|
security: [%{"oAuth" => ["admin:write"]}],
|
||||||
parameters: [
|
parameters: [
|
||||||
url_param(),
|
url_param(),
|
||||||
Operation.parameter(
|
Operation.parameter(
|
||||||
|
@ -115,10 +115,10 @@ def archive_operation do
|
||||||
|
|
||||||
def download_operation do
|
def download_operation do
|
||||||
%Operation{
|
%Operation{
|
||||||
tags: ["Emoji packs"],
|
tags: ["Emoji pack administration"],
|
||||||
summary: "Download pack from another instance",
|
summary: "Download pack from another instance",
|
||||||
operationId: "PleromaAPI.EmojiPackController.download",
|
operationId: "PleromaAPI.EmojiPackController.download",
|
||||||
security: [%{"oAuth" => ["write"]}],
|
security: [%{"oAuth" => ["admin:write"]}],
|
||||||
requestBody: request_body("Parameters", download_request(), required: true),
|
requestBody: request_body("Parameters", download_request(), required: true),
|
||||||
responses: %{
|
responses: %{
|
||||||
200 => ok_response(),
|
200 => ok_response(),
|
||||||
|
@ -145,10 +145,10 @@ defp download_request do
|
||||||
|
|
||||||
def create_operation do
|
def create_operation do
|
||||||
%Operation{
|
%Operation{
|
||||||
tags: ["Emoji packs"],
|
tags: ["Emoji pack administration"],
|
||||||
summary: "Create an empty pack",
|
summary: "Create an empty pack",
|
||||||
operationId: "PleromaAPI.EmojiPackController.create",
|
operationId: "PleromaAPI.EmojiPackController.create",
|
||||||
security: [%{"oAuth" => ["write"]}],
|
security: [%{"oAuth" => ["admin:write"]}],
|
||||||
parameters: [name_param()],
|
parameters: [name_param()],
|
||||||
responses: %{
|
responses: %{
|
||||||
200 => ok_response(),
|
200 => ok_response(),
|
||||||
|
@ -161,10 +161,10 @@ def create_operation do
|
||||||
|
|
||||||
def delete_operation do
|
def delete_operation do
|
||||||
%Operation{
|
%Operation{
|
||||||
tags: ["Emoji packs"],
|
tags: ["Emoji pack administration"],
|
||||||
summary: "Delete a custom emoji pack",
|
summary: "Delete a custom emoji pack",
|
||||||
operationId: "PleromaAPI.EmojiPackController.delete",
|
operationId: "PleromaAPI.EmojiPackController.delete",
|
||||||
security: [%{"oAuth" => ["write"]}],
|
security: [%{"oAuth" => ["admin:write"]}],
|
||||||
parameters: [name_param()],
|
parameters: [name_param()],
|
||||||
responses: %{
|
responses: %{
|
||||||
200 => ok_response(),
|
200 => ok_response(),
|
||||||
|
@ -177,10 +177,10 @@ def delete_operation do
|
||||||
|
|
||||||
def update_operation do
|
def update_operation do
|
||||||
%Operation{
|
%Operation{
|
||||||
tags: ["Emoji packs"],
|
tags: ["Emoji pack administration"],
|
||||||
summary: "Updates (replaces) pack metadata",
|
summary: "Updates (replaces) pack metadata",
|
||||||
operationId: "PleromaAPI.EmojiPackController.update",
|
operationId: "PleromaAPI.EmojiPackController.update",
|
||||||
security: [%{"oAuth" => ["write"]}],
|
security: [%{"oAuth" => ["admin:write"]}],
|
||||||
requestBody: request_body("Parameters", update_request(), required: true),
|
requestBody: request_body("Parameters", update_request(), required: true),
|
||||||
parameters: [name_param()],
|
parameters: [name_param()],
|
||||||
responses: %{
|
responses: %{
|
||||||
|
@ -193,10 +193,10 @@ def update_operation do
|
||||||
|
|
||||||
def import_from_filesystem_operation do
|
def import_from_filesystem_operation do
|
||||||
%Operation{
|
%Operation{
|
||||||
tags: ["Emoji packs"],
|
tags: ["Emoji pack administration"],
|
||||||
summary: "Imports packs from filesystem",
|
summary: "Imports packs from filesystem",
|
||||||
operationId: "PleromaAPI.EmojiPackController.import",
|
operationId: "PleromaAPI.EmojiPackController.import",
|
||||||
security: [%{"oAuth" => ["write"]}],
|
security: [%{"oAuth" => ["admin:write"]}],
|
||||||
responses: %{
|
responses: %{
|
||||||
200 =>
|
200 =>
|
||||||
Operation.response("Array of imported pack names", "application/json", %Schema{
|
Operation.response("Array of imported pack names", "application/json", %Schema{
|
||||||
|
|
|
@ -52,7 +52,8 @@ defmodule Pleroma.Web.ApiSpec.Schemas.ChatMessage do
|
||||||
title: %Schema{type: :string, description: "Title of linked resource"},
|
title: %Schema{type: :string, description: "Title of linked resource"},
|
||||||
description: %Schema{type: :string, description: "Description of preview"}
|
description: %Schema{type: :string, description: "Description of preview"}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
unread: %Schema{type: :boolean, description: "Whether a message has been marked as read."}
|
||||||
},
|
},
|
||||||
example: %{
|
example: %{
|
||||||
"account_id" => "someflakeid",
|
"account_id" => "someflakeid",
|
||||||
|
@ -69,7 +70,8 @@ defmodule Pleroma.Web.ApiSpec.Schemas.ChatMessage do
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"id" => "14",
|
"id" => "14",
|
||||||
"attachment" => nil
|
"attachment" => nil,
|
||||||
|
"unread" => false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,6 +3,11 @@
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.MastodonAPI.AppController do
|
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
|
use Pleroma.Web, :controller
|
||||||
|
|
||||||
alias Pleroma.Repo
|
alias Pleroma.Repo
|
||||||
|
@ -17,11 +22,9 @@ defmodule Pleroma.Web.MastodonAPI.AppController do
|
||||||
plug(
|
plug(
|
||||||
:skip_plug,
|
:skip_plug,
|
||||||
[OAuthScopesPlug, EnsurePublicOrAuthenticatedPlug]
|
[OAuthScopesPlug, EnsurePublicOrAuthenticatedPlug]
|
||||||
when action == :create
|
when action in [:create, :verify_credentials]
|
||||||
)
|
)
|
||||||
|
|
||||||
plug(OAuthScopesPlug, %{scopes: ["read"]} when action == :verify_credentials)
|
|
||||||
|
|
||||||
plug(Pleroma.Web.ApiSpec.CastAndValidate)
|
plug(Pleroma.Web.ApiSpec.CastAndValidate)
|
||||||
|
|
||||||
@local_mastodon_name "Mastodon-Local"
|
@local_mastodon_name "Mastodon-Local"
|
||||||
|
@ -44,10 +47,13 @@ def create(%{body_params: params} = conn, _params) do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc "GET /api/v1/apps/verify_credentials"
|
@doc """
|
||||||
def verify_credentials(%{assigns: %{user: _user, token: token}} = conn, _) do
|
GET /api/v1/apps/verify_credentials
|
||||||
with %Token{app: %App{} = app} <- Repo.preload(token, :app) do
|
Gets compact non-secret representation of the app. Supports app tokens and user tokens.
|
||||||
render(conn, "short.json", app: app)
|
"""
|
||||||
|
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
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -36,4 +36,13 @@ def mark_as_read(%{assigns: %{user: user}} = conn, %{id: participation_id}) do
|
||||||
render(conn, "participation.json", participation: participation, for: user)
|
render(conn, "participation.json", participation: participation, for: user)
|
||||||
end
|
end
|
||||||
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
|
end
|
||||||
|
|
|
@ -34,10 +34,10 @@ def render("show.json", %{app: %App{} = app}) do
|
||||||
|> with_vapid_key()
|
|> with_vapid_key()
|
||||||
end
|
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,
|
name: name,
|
||||||
website: webiste
|
website: website
|
||||||
}
|
}
|
||||||
|> with_vapid_key()
|
|> with_vapid_key()
|
||||||
end
|
end
|
||||||
|
|
|
@ -35,7 +35,7 @@ defmodule Pleroma.Web.PleromaAPI.ChatController do
|
||||||
|
|
||||||
plug(
|
plug(
|
||||||
OAuthScopesPlug,
|
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(OpenApiSpex.Plug.CastAndValidate, render_error: Pleroma.Web.ApiSpec.RenderError)
|
||||||
|
@ -138,18 +138,30 @@ def messages(%{assigns: %{user: user}} = conn, %{id: id} = params) do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def index(%{assigns: %{user: %{id: user_id} = user}} = conn, params) do
|
def index(%{assigns: %{user: user}} = conn, params) do
|
||||||
|
chats =
|
||||||
|
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 =
|
exclude_users =
|
||||||
User.cached_blocked_users_ap_ids(user) ++
|
User.cached_blocked_users_ap_ids(user) ++
|
||||||
if params[:with_muted], do: [], else: User.cached_muted_users_ap_ids(user)
|
if params[:with_muted], do: [], else: User.cached_muted_users_ap_ids(user)
|
||||||
|
|
||||||
chats =
|
user_id
|
||||||
user_id
|
|> Chat.for_user_query()
|
||||||
|> Chat.for_user_query()
|
|> where([c], c.recipient not in ^exclude_users)
|
||||||
|> where([c], c.recipient not in ^exclude_users)
|
|
||||||
|> Repo.all()
|
|
||||||
|
|
||||||
render(conn, "index.json", chats: chats)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def create(%{assigns: %{user: user}} = conn, %{id: id}) do
|
def create(%{assigns: %{user: user}} = conn, %{id: id}) do
|
||||||
|
|
|
@ -12,7 +12,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiFileController do
|
||||||
|
|
||||||
plug(
|
plug(
|
||||||
Pleroma.Web.Plugs.OAuthScopesPlug,
|
Pleroma.Web.Plugs.OAuthScopesPlug,
|
||||||
%{scopes: ["write"], admin: true}
|
%{scopes: ["admin:write"]}
|
||||||
when action in [
|
when action in [
|
||||||
:create,
|
:create,
|
||||||
:update,
|
:update,
|
||||||
|
|
|
@ -11,7 +11,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiPackController do
|
||||||
|
|
||||||
plug(
|
plug(
|
||||||
Pleroma.Web.Plugs.OAuthScopesPlug,
|
Pleroma.Web.Plugs.OAuthScopesPlug,
|
||||||
%{scopes: ["write"], admin: true}
|
%{scopes: ["admin:write"]}
|
||||||
when action in [
|
when action in [
|
||||||
:import_from_filesystem,
|
:import_from_filesystem,
|
||||||
:remote,
|
:remote,
|
||||||
|
|
|
@ -3,6 +3,10 @@
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.Plugs.EnsureAuthenticatedPlug do
|
defmodule Pleroma.Web.Plugs.EnsureAuthenticatedPlug do
|
||||||
|
@moduledoc """
|
||||||
|
Ensures _user_ authentication (app-bound user-unbound tokens are not accepted).
|
||||||
|
"""
|
||||||
|
|
||||||
import Plug.Conn
|
import Plug.Conn
|
||||||
import Pleroma.Web.TranslationHelpers
|
import Pleroma.Web.TranslationHelpers
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,11 @@
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.Plugs.EnsurePublicOrAuthenticatedPlug do
|
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 Pleroma.Web.TranslationHelpers
|
||||||
import Plug.Conn
|
import Plug.Conn
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,11 @@ def call(%{assigns: %{user: %User{id: user_id}} = assigns} = conn, _) do
|
||||||
end
|
end
|
||||||
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
|
def call(conn, _) do
|
||||||
conn
|
conn
|
||||||
|> assign(:user, nil)
|
|> assign(:user, nil)
|
||||||
|
|
|
@ -6,7 +6,6 @@ defmodule Pleroma.Web.Plugs.OAuthScopesPlug do
|
||||||
import Plug.Conn
|
import Plug.Conn
|
||||||
import Pleroma.Web.Gettext
|
import Pleroma.Web.Gettext
|
||||||
|
|
||||||
alias Pleroma.Config
|
|
||||||
alias Pleroma.Helpers.AuthHelper
|
alias Pleroma.Helpers.AuthHelper
|
||||||
|
|
||||||
use Pleroma.Web, :plug
|
use Pleroma.Web, :plug
|
||||||
|
@ -18,7 +17,6 @@ def perform(%Plug.Conn{assigns: assigns} = conn, %{scopes: scopes} = options) do
|
||||||
op = options[:op] || :|
|
op = options[:op] || :|
|
||||||
token = assigns[:token]
|
token = assigns[:token]
|
||||||
|
|
||||||
scopes = transform_scopes(scopes, options)
|
|
||||||
matched_scopes = (token && filter_descendants(scopes, token.scopes)) || []
|
matched_scopes = (token && filter_descendants(scopes, token.scopes)) || []
|
||||||
|
|
||||||
cond do
|
cond do
|
||||||
|
@ -57,13 +55,4 @@ def filter_descendants(scopes, supported_scopes) do
|
||||||
end
|
end
|
||||||
)
|
)
|
||||||
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
|
end
|
||||||
|
|
|
@ -37,11 +37,13 @@ defmodule Pleroma.Web.Router do
|
||||||
plug(Pleroma.Web.Plugs.EnsureUserTokenAssignsPlug)
|
plug(Pleroma.Web.Plugs.EnsureUserTokenAssignsPlug)
|
||||||
end
|
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)
|
plug(Pleroma.Web.Plugs.ExpectAuthenticatedCheckPlug)
|
||||||
end
|
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)
|
plug(Pleroma.Web.Plugs.ExpectPublicOrAuthenticatedCheckPlug)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -66,23 +68,30 @@ defmodule Pleroma.Web.Router do
|
||||||
plug(OpenApiSpex.Plug.PutApiSpec, module: Pleroma.Web.ApiSpec)
|
plug(OpenApiSpex.Plug.PutApiSpec, module: Pleroma.Web.ApiSpec)
|
||||||
end
|
end
|
||||||
|
|
||||||
pipeline :api do
|
pipeline :no_auth_or_privacy_expectations_api do
|
||||||
plug(:expect_public_instance_or_authentication)
|
|
||||||
plug(:base_api)
|
plug(:base_api)
|
||||||
plug(:after_auth)
|
plug(:after_auth)
|
||||||
plug(Pleroma.Web.Plugs.IdempotencyPlug)
|
plug(Pleroma.Web.Plugs.IdempotencyPlug)
|
||||||
end
|
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
|
pipeline :authenticated_api do
|
||||||
plug(:expect_authentication)
|
plug(:expect_user_authentication)
|
||||||
plug(:base_api)
|
plug(:no_auth_or_privacy_expectations_api)
|
||||||
plug(:after_auth)
|
|
||||||
plug(Pleroma.Web.Plugs.EnsureAuthenticatedPlug)
|
plug(Pleroma.Web.Plugs.EnsureAuthenticatedPlug)
|
||||||
plug(Pleroma.Web.Plugs.IdempotencyPlug)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
pipeline :admin_api do
|
pipeline :admin_api do
|
||||||
plug(:expect_authentication)
|
plug(:expect_user_authentication)
|
||||||
plug(:base_api)
|
plug(:base_api)
|
||||||
plug(Pleroma.Web.Plugs.AdminSecretAuthenticationPlug)
|
plug(Pleroma.Web.Plugs.AdminSecretAuthenticationPlug)
|
||||||
plug(:after_auth)
|
plug(:after_auth)
|
||||||
|
@ -411,6 +420,13 @@ defmodule Pleroma.Web.Router do
|
||||||
get("/federation_status", InstancesController, :show)
|
get("/federation_status", InstancesController, :show)
|
||||||
end
|
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
|
scope "/api/v1", Pleroma.Web.MastodonAPI do
|
||||||
pipe_through(:authenticated_api)
|
pipe_through(:authenticated_api)
|
||||||
|
|
||||||
|
@ -432,10 +448,9 @@ defmodule Pleroma.Web.Router do
|
||||||
post("/accounts/:id/mute", AccountController, :mute)
|
post("/accounts/:id/mute", AccountController, :mute)
|
||||||
post("/accounts/:id/unmute", AccountController, :unmute)
|
post("/accounts/:id/unmute", AccountController, :unmute)
|
||||||
|
|
||||||
get("/apps/verify_credentials", AppController, :verify_credentials)
|
|
||||||
|
|
||||||
get("/conversations", ConversationController, :index)
|
get("/conversations", ConversationController, :index)
|
||||||
post("/conversations/:id/read", ConversationController, :mark_as_read)
|
post("/conversations/:id/read", ConversationController, :mark_as_read)
|
||||||
|
delete("/conversations/:id", ConversationController, :delete)
|
||||||
|
|
||||||
get("/domain_blocks", DomainBlockController, :index)
|
get("/domain_blocks", DomainBlockController, :index)
|
||||||
post("/domain_blocks", DomainBlockController, :create)
|
post("/domain_blocks", DomainBlockController, :create)
|
||||||
|
@ -524,6 +539,13 @@ defmodule Pleroma.Web.Router do
|
||||||
put("/settings", MastoFEController, :put_settings)
|
put("/settings", MastoFEController, :put_settings)
|
||||||
end
|
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
|
scope "/api/v1", Pleroma.Web.MastodonAPI do
|
||||||
pipe_through(:api)
|
pipe_through(:api)
|
||||||
|
|
||||||
|
@ -540,8 +562,6 @@ defmodule Pleroma.Web.Router do
|
||||||
get("/instance", InstanceController, :show)
|
get("/instance", InstanceController, :show)
|
||||||
get("/instance/peers", InstanceController, :peers)
|
get("/instance/peers", InstanceController, :peers)
|
||||||
|
|
||||||
post("/apps", AppController, :create)
|
|
||||||
|
|
||||||
get("/statuses", StatusController, :index)
|
get("/statuses", StatusController, :index)
|
||||||
get("/statuses/:id", StatusController, :show)
|
get("/statuses/:id", StatusController, :show)
|
||||||
get("/statuses/:id/context", StatusController, :context)
|
get("/statuses/:id/context", StatusController, :context)
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 726 B After Width: | Height: | Size: 1.0 KiB |
|
@ -359,4 +359,16 @@ test "the conversation with the blocked user is not marked as unread on a reply"
|
||||||
assert Participation.unread_count(blocked) == 1
|
assert Participation.unread_count(blocked) == 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "deletes a conversation" do
|
||||||
|
user = insert(:user)
|
||||||
|
other_user = insert(:user)
|
||||||
|
|
||||||
|
{:ok, _activity} =
|
||||||
|
CommonAPI.post(user, %{status: "Hey @#{other_user.nickname}.", visibility: "direct"})
|
||||||
|
|
||||||
|
assert [participation] = Participation.for_user(other_user)
|
||||||
|
assert {:ok, _} = Participation.delete(participation)
|
||||||
|
assert [] == Participation.for_user(other_user)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -46,104 +46,47 @@ test "with valid `admin_token` query parameter, skips OAuth scopes check" do
|
||||||
assert json_response(conn, 200)
|
assert json_response(conn, 200)
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "with [:auth, :enforce_oauth_admin_scope_usage]," do
|
test "GET /api/pleroma/admin/users/:nickname requires admin:read:accounts or broader scope",
|
||||||
setup do: clear_config([:auth, :enforce_oauth_admin_scope_usage], true)
|
%{admin: admin} do
|
||||||
|
user = insert(:user)
|
||||||
|
url = "/api/pleroma/admin/users/#{user.nickname}"
|
||||||
|
|
||||||
test "GET /api/pleroma/admin/users/:nickname requires admin:read:accounts or broader scope",
|
good_token1 = insert(:oauth_token, user: admin, scopes: ["admin"])
|
||||||
%{admin: admin} do
|
good_token2 = insert(:oauth_token, user: admin, scopes: ["admin:read"])
|
||||||
user = insert(:user)
|
good_token3 = insert(:oauth_token, user: admin, scopes: ["admin:read:accounts"])
|
||||||
url = "/api/pleroma/admin/users/#{user.nickname}"
|
|
||||||
|
|
||||||
good_token1 = insert(:oauth_token, user: admin, scopes: ["admin"])
|
bad_token1 = insert(:oauth_token, user: admin, scopes: ["read:accounts"])
|
||||||
good_token2 = insert(:oauth_token, user: admin, scopes: ["admin:read"])
|
bad_token2 = insert(:oauth_token, user: admin, scopes: ["admin:read:accounts:partial"])
|
||||||
good_token3 = insert(:oauth_token, user: admin, scopes: ["admin:read:accounts"])
|
bad_token3 = nil
|
||||||
|
|
||||||
bad_token1 = insert(:oauth_token, user: admin, scopes: ["read:accounts"])
|
for good_token <- [good_token1, good_token2, good_token3] do
|
||||||
bad_token2 = insert(:oauth_token, user: admin, scopes: ["admin:read:accounts:partial"])
|
conn =
|
||||||
bad_token3 = nil
|
build_conn()
|
||||||
|
|> assign(:user, admin)
|
||||||
|
|> assign(:token, good_token)
|
||||||
|
|> get(url)
|
||||||
|
|
||||||
for good_token <- [good_token1, good_token2, good_token3] do
|
assert json_response(conn, 200)
|
||||||
conn =
|
|
||||||
build_conn()
|
|
||||||
|> assign(:user, admin)
|
|
||||||
|> assign(:token, good_token)
|
|
||||||
|> get(url)
|
|
||||||
|
|
||||||
assert json_response(conn, 200)
|
|
||||||
end
|
|
||||||
|
|
||||||
for good_token <- [good_token1, good_token2, good_token3] do
|
|
||||||
conn =
|
|
||||||
build_conn()
|
|
||||||
|> assign(:user, nil)
|
|
||||||
|> assign(:token, good_token)
|
|
||||||
|> get(url)
|
|
||||||
|
|
||||||
assert json_response(conn, :forbidden)
|
|
||||||
end
|
|
||||||
|
|
||||||
for bad_token <- [bad_token1, bad_token2, bad_token3] do
|
|
||||||
conn =
|
|
||||||
build_conn()
|
|
||||||
|> assign(:user, admin)
|
|
||||||
|> assign(:token, bad_token)
|
|
||||||
|> get(url)
|
|
||||||
|
|
||||||
assert json_response(conn, :forbidden)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
describe "unless [:auth, :enforce_oauth_admin_scope_usage]," do
|
for good_token <- [good_token1, good_token2, good_token3] do
|
||||||
setup do: clear_config([:auth, :enforce_oauth_admin_scope_usage], false)
|
conn =
|
||||||
|
build_conn()
|
||||||
|
|> assign(:user, nil)
|
||||||
|
|> assign(:token, good_token)
|
||||||
|
|> get(url)
|
||||||
|
|
||||||
test "GET /api/pleroma/admin/users/:nickname requires " <>
|
assert json_response(conn, :forbidden)
|
||||||
"read:accounts or admin:read:accounts or broader scope",
|
end
|
||||||
%{admin: admin} do
|
|
||||||
user = insert(:user)
|
|
||||||
url = "/api/pleroma/admin/users/#{user.nickname}"
|
|
||||||
|
|
||||||
good_token1 = insert(:oauth_token, user: admin, scopes: ["admin"])
|
for bad_token <- [bad_token1, bad_token2, bad_token3] do
|
||||||
good_token2 = insert(:oauth_token, user: admin, scopes: ["admin:read"])
|
conn =
|
||||||
good_token3 = insert(:oauth_token, user: admin, scopes: ["admin:read:accounts"])
|
build_conn()
|
||||||
good_token4 = insert(:oauth_token, user: admin, scopes: ["read:accounts"])
|
|> assign(:user, admin)
|
||||||
good_token5 = insert(:oauth_token, user: admin, scopes: ["read"])
|
|> assign(:token, bad_token)
|
||||||
|
|> get(url)
|
||||||
|
|
||||||
good_tokens = [good_token1, good_token2, good_token3, good_token4, good_token5]
|
assert json_response(conn, :forbidden)
|
||||||
|
|
||||||
bad_token1 = insert(:oauth_token, user: admin, scopes: ["read:accounts:partial"])
|
|
||||||
bad_token2 = insert(:oauth_token, user: admin, scopes: ["admin:read:accounts:partial"])
|
|
||||||
bad_token3 = nil
|
|
||||||
|
|
||||||
for good_token <- good_tokens do
|
|
||||||
conn =
|
|
||||||
build_conn()
|
|
||||||
|> assign(:user, admin)
|
|
||||||
|> assign(:token, good_token)
|
|
||||||
|> get(url)
|
|
||||||
|
|
||||||
assert json_response(conn, 200)
|
|
||||||
end
|
|
||||||
|
|
||||||
for good_token <- good_tokens do
|
|
||||||
conn =
|
|
||||||
build_conn()
|
|
||||||
|> assign(:user, nil)
|
|
||||||
|> assign(:token, good_token)
|
|
||||||
|> get(url)
|
|
||||||
|
|
||||||
assert json_response(conn, :forbidden)
|
|
||||||
end
|
|
||||||
|
|
||||||
for bad_token <- [bad_token1, bad_token2, bad_token3] do
|
|
||||||
conn =
|
|
||||||
build_conn()
|
|
||||||
|> assign(:user, admin)
|
|
||||||
|> assign(:token, bad_token)
|
|
||||||
|> get(url)
|
|
||||||
|
|
||||||
assert json_response(conn, :forbidden)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -47,104 +47,47 @@ test "with valid `admin_token` query parameter, skips OAuth scopes check" do
|
||||||
assert json_response(conn, 200)
|
assert json_response(conn, 200)
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "with [:auth, :enforce_oauth_admin_scope_usage]," do
|
test "GET /api/pleroma/admin/users/:nickname requires admin:read:accounts or broader scope",
|
||||||
setup do: clear_config([:auth, :enforce_oauth_admin_scope_usage], true)
|
%{admin: admin} do
|
||||||
|
user = insert(:user)
|
||||||
|
url = "/api/pleroma/admin/users/#{user.nickname}"
|
||||||
|
|
||||||
test "GET /api/pleroma/admin/users/:nickname requires admin:read:accounts or broader scope",
|
good_token1 = insert(:oauth_token, user: admin, scopes: ["admin"])
|
||||||
%{admin: admin} do
|
good_token2 = insert(:oauth_token, user: admin, scopes: ["admin:read"])
|
||||||
user = insert(:user)
|
good_token3 = insert(:oauth_token, user: admin, scopes: ["admin:read:accounts"])
|
||||||
url = "/api/pleroma/admin/users/#{user.nickname}"
|
|
||||||
|
|
||||||
good_token1 = insert(:oauth_token, user: admin, scopes: ["admin"])
|
bad_token1 = insert(:oauth_token, user: admin, scopes: ["read:accounts"])
|
||||||
good_token2 = insert(:oauth_token, user: admin, scopes: ["admin:read"])
|
bad_token2 = insert(:oauth_token, user: admin, scopes: ["admin:read:accounts:partial"])
|
||||||
good_token3 = insert(:oauth_token, user: admin, scopes: ["admin:read:accounts"])
|
bad_token3 = nil
|
||||||
|
|
||||||
bad_token1 = insert(:oauth_token, user: admin, scopes: ["read:accounts"])
|
for good_token <- [good_token1, good_token2, good_token3] do
|
||||||
bad_token2 = insert(:oauth_token, user: admin, scopes: ["admin:read:accounts:partial"])
|
conn =
|
||||||
bad_token3 = nil
|
build_conn()
|
||||||
|
|> assign(:user, admin)
|
||||||
|
|> assign(:token, good_token)
|
||||||
|
|> get(url)
|
||||||
|
|
||||||
for good_token <- [good_token1, good_token2, good_token3] do
|
assert json_response(conn, 200)
|
||||||
conn =
|
|
||||||
build_conn()
|
|
||||||
|> assign(:user, admin)
|
|
||||||
|> assign(:token, good_token)
|
|
||||||
|> get(url)
|
|
||||||
|
|
||||||
assert json_response(conn, 200)
|
|
||||||
end
|
|
||||||
|
|
||||||
for good_token <- [good_token1, good_token2, good_token3] do
|
|
||||||
conn =
|
|
||||||
build_conn()
|
|
||||||
|> assign(:user, nil)
|
|
||||||
|> assign(:token, good_token)
|
|
||||||
|> get(url)
|
|
||||||
|
|
||||||
assert json_response(conn, :forbidden)
|
|
||||||
end
|
|
||||||
|
|
||||||
for bad_token <- [bad_token1, bad_token2, bad_token3] do
|
|
||||||
conn =
|
|
||||||
build_conn()
|
|
||||||
|> assign(:user, admin)
|
|
||||||
|> assign(:token, bad_token)
|
|
||||||
|> get(url)
|
|
||||||
|
|
||||||
assert json_response(conn, :forbidden)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
describe "unless [:auth, :enforce_oauth_admin_scope_usage]," do
|
for good_token <- [good_token1, good_token2, good_token3] do
|
||||||
setup do: clear_config([:auth, :enforce_oauth_admin_scope_usage], false)
|
conn =
|
||||||
|
build_conn()
|
||||||
|
|> assign(:user, nil)
|
||||||
|
|> assign(:token, good_token)
|
||||||
|
|> get(url)
|
||||||
|
|
||||||
test "GET /api/pleroma/admin/users/:nickname requires " <>
|
assert json_response(conn, :forbidden)
|
||||||
"read:accounts or admin:read:accounts or broader scope",
|
end
|
||||||
%{admin: admin} do
|
|
||||||
user = insert(:user)
|
|
||||||
url = "/api/pleroma/admin/users/#{user.nickname}"
|
|
||||||
|
|
||||||
good_token1 = insert(:oauth_token, user: admin, scopes: ["admin"])
|
for bad_token <- [bad_token1, bad_token2, bad_token3] do
|
||||||
good_token2 = insert(:oauth_token, user: admin, scopes: ["admin:read"])
|
conn =
|
||||||
good_token3 = insert(:oauth_token, user: admin, scopes: ["admin:read:accounts"])
|
build_conn()
|
||||||
good_token4 = insert(:oauth_token, user: admin, scopes: ["read:accounts"])
|
|> assign(:user, admin)
|
||||||
good_token5 = insert(:oauth_token, user: admin, scopes: ["read"])
|
|> assign(:token, bad_token)
|
||||||
|
|> get(url)
|
||||||
|
|
||||||
good_tokens = [good_token1, good_token2, good_token3, good_token4, good_token5]
|
assert json_response(conn, :forbidden)
|
||||||
|
|
||||||
bad_token1 = insert(:oauth_token, user: admin, scopes: ["read:accounts:partial"])
|
|
||||||
bad_token2 = insert(:oauth_token, user: admin, scopes: ["admin:read:accounts:partial"])
|
|
||||||
bad_token3 = nil
|
|
||||||
|
|
||||||
for good_token <- good_tokens do
|
|
||||||
conn =
|
|
||||||
build_conn()
|
|
||||||
|> assign(:user, admin)
|
|
||||||
|> assign(:token, good_token)
|
|
||||||
|> get(url)
|
|
||||||
|
|
||||||
assert json_response(conn, 200)
|
|
||||||
end
|
|
||||||
|
|
||||||
for good_token <- good_tokens do
|
|
||||||
conn =
|
|
||||||
build_conn()
|
|
||||||
|> assign(:user, nil)
|
|
||||||
|> assign(:token, good_token)
|
|
||||||
|> get(url)
|
|
||||||
|
|
||||||
assert json_response(conn, :forbidden)
|
|
||||||
end
|
|
||||||
|
|
||||||
for bad_token <- [bad_token1, bad_token2, bad_token3] do
|
|
||||||
conn =
|
|
||||||
build_conn()
|
|
||||||
|> assign(:user, admin)
|
|
||||||
|> assign(:token, bad_token)
|
|
||||||
|> get(url)
|
|
||||||
|
|
||||||
assert json_response(conn, :forbidden)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -12,22 +12,26 @@ defmodule Pleroma.Web.MastodonAPI.AppControllerTest do
|
||||||
import Pleroma.Factory
|
import Pleroma.Factory
|
||||||
|
|
||||||
test "apps/verify_credentials", %{conn: conn} do
|
test "apps/verify_credentials", %{conn: conn} do
|
||||||
token = insert(:oauth_token)
|
user_bound_token = insert(:oauth_token)
|
||||||
|
app_bound_token = insert(:oauth_token, user: nil)
|
||||||
|
refute app_bound_token.user
|
||||||
|
|
||||||
conn =
|
for token <- [app_bound_token, user_bound_token] do
|
||||||
conn
|
conn =
|
||||||
|> put_req_header("authorization", "Bearer #{token.token}")
|
conn
|
||||||
|> get("/api/v1/apps/verify_credentials")
|
|> put_req_header("authorization", "Bearer #{token.token}")
|
||||||
|
|> get("/api/v1/apps/verify_credentials")
|
||||||
|
|
||||||
app = Repo.preload(token, :app).app
|
app = Repo.preload(token, :app).app
|
||||||
|
|
||||||
expected = %{
|
expected = %{
|
||||||
"name" => app.client_name,
|
"name" => app.client_name,
|
||||||
"website" => app.website,
|
"website" => app.website,
|
||||||
"vapid_key" => Push.vapid_config() |> Keyword.get(:public_key)
|
"vapid_key" => Push.vapid_config() |> Keyword.get(:public_key)
|
||||||
}
|
}
|
||||||
|
|
||||||
assert expected == json_response_and_validate_schema(conn, 200)
|
assert expected == json_response_and_validate_schema(conn, 200)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
test "creates an oauth app", %{conn: conn} do
|
test "creates an oauth app", %{conn: conn} do
|
||||||
|
|
|
@ -217,6 +217,32 @@ test "(vanilla) Mastodon frontend behaviour", %{user: user_one, conn: conn} do
|
||||||
assert %{"ancestors" => [], "descendants" => []} == json_response(res_conn, 200)
|
assert %{"ancestors" => [], "descendants" => []} == json_response(res_conn, 200)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "Removes a conversation", %{user: user_one, conn: conn} do
|
||||||
|
user_two = insert(:user)
|
||||||
|
token = insert(:oauth_token, user: user_one, scopes: ["read:statuses", "write:conversations"])
|
||||||
|
|
||||||
|
{:ok, _direct} = create_direct_message(user_one, [user_two])
|
||||||
|
{:ok, _direct} = create_direct_message(user_one, [user_two])
|
||||||
|
|
||||||
|
assert [%{"id" => conv1_id}, %{"id" => conv2_id}] =
|
||||||
|
conn
|
||||||
|
|> assign(:token, token)
|
||||||
|
|> get("/api/v1/conversations")
|
||||||
|
|> json_response_and_validate_schema(200)
|
||||||
|
|
||||||
|
assert %{} =
|
||||||
|
conn
|
||||||
|
|> assign(:token, token)
|
||||||
|
|> delete("/api/v1/conversations/#{conv1_id}")
|
||||||
|
|> json_response_and_validate_schema(200)
|
||||||
|
|
||||||
|
assert [%{"id" => ^conv2_id}] =
|
||||||
|
conn
|
||||||
|
|> assign(:token, token)
|
||||||
|
|> get("/api/v1/conversations")
|
||||||
|
|> json_response_and_validate_schema(200)
|
||||||
|
end
|
||||||
|
|
||||||
defp create_direct_message(sender, recips) do
|
defp create_direct_message(sender, recips) do
|
||||||
hellos =
|
hellos =
|
||||||
recips
|
recips
|
||||||
|
|
|
@ -304,139 +304,165 @@ test "it returns a chat", %{conn: conn, user: user} do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "GET /api/v1/pleroma/chats" do
|
for tested_endpoint <- ["/api/v1/pleroma/chats", "/api/v2/pleroma/chats"] do
|
||||||
setup do: oauth_access(["read:chats"])
|
describe "GET #{tested_endpoint}" do
|
||||||
|
setup do: oauth_access(["read:chats"])
|
||||||
|
|
||||||
test "it does not return chats with deleted users", %{conn: conn, user: user} do
|
test "it does not return chats with deleted users", %{conn: conn, user: user} do
|
||||||
recipient = insert(:user)
|
|
||||||
{:ok, _} = Chat.get_or_create(user.id, recipient.ap_id)
|
|
||||||
|
|
||||||
Pleroma.Repo.delete(recipient)
|
|
||||||
User.invalidate_cache(recipient)
|
|
||||||
|
|
||||||
result =
|
|
||||||
conn
|
|
||||||
|> get("/api/v1/pleroma/chats")
|
|
||||||
|> json_response_and_validate_schema(200)
|
|
||||||
|
|
||||||
assert length(result) == 0
|
|
||||||
end
|
|
||||||
|
|
||||||
test "it does not return chats with users you blocked", %{conn: conn, user: user} do
|
|
||||||
recipient = insert(:user)
|
|
||||||
|
|
||||||
{:ok, _} = Chat.get_or_create(user.id, recipient.ap_id)
|
|
||||||
|
|
||||||
result =
|
|
||||||
conn
|
|
||||||
|> get("/api/v1/pleroma/chats")
|
|
||||||
|> json_response_and_validate_schema(200)
|
|
||||||
|
|
||||||
assert length(result) == 1
|
|
||||||
|
|
||||||
User.block(user, recipient)
|
|
||||||
|
|
||||||
result =
|
|
||||||
conn
|
|
||||||
|> get("/api/v1/pleroma/chats")
|
|
||||||
|> json_response_and_validate_schema(200)
|
|
||||||
|
|
||||||
assert length(result) == 0
|
|
||||||
end
|
|
||||||
|
|
||||||
test "it does not return chats with users you muted", %{conn: conn, user: user} do
|
|
||||||
recipient = insert(:user)
|
|
||||||
|
|
||||||
{:ok, _} = Chat.get_or_create(user.id, recipient.ap_id)
|
|
||||||
|
|
||||||
result =
|
|
||||||
conn
|
|
||||||
|> get("/api/v1/pleroma/chats")
|
|
||||||
|> json_response_and_validate_schema(200)
|
|
||||||
|
|
||||||
assert length(result) == 1
|
|
||||||
|
|
||||||
User.mute(user, recipient)
|
|
||||||
|
|
||||||
result =
|
|
||||||
conn
|
|
||||||
|> get("/api/v1/pleroma/chats")
|
|
||||||
|> json_response_and_validate_schema(200)
|
|
||||||
|
|
||||||
assert length(result) == 0
|
|
||||||
|
|
||||||
result =
|
|
||||||
conn
|
|
||||||
|> get("/api/v1/pleroma/chats?with_muted=true")
|
|
||||||
|> json_response_and_validate_schema(200)
|
|
||||||
|
|
||||||
assert length(result) == 1
|
|
||||||
end
|
|
||||||
|
|
||||||
test "it returns all chats", %{conn: conn, user: user} do
|
|
||||||
Enum.each(1..30, fn _ ->
|
|
||||||
recipient = insert(:user)
|
recipient = insert(:user)
|
||||||
{:ok, _} = Chat.get_or_create(user.id, recipient.ap_id)
|
{:ok, _} = Chat.get_or_create(user.id, recipient.ap_id)
|
||||||
end)
|
|
||||||
|
|
||||||
result =
|
Pleroma.Repo.delete(recipient)
|
||||||
conn
|
User.invalidate_cache(recipient)
|
||||||
|> get("/api/v1/pleroma/chats")
|
|
||||||
|> json_response_and_validate_schema(200)
|
|
||||||
|
|
||||||
assert length(result) == 30
|
result =
|
||||||
end
|
conn
|
||||||
|
|> get(unquote(tested_endpoint))
|
||||||
|
|> json_response_and_validate_schema(200)
|
||||||
|
|
||||||
test "it return a list of chats the current user is participating in, in descending order of updates",
|
assert length(result) == 0
|
||||||
%{conn: conn, user: user} do
|
end
|
||||||
har = insert(:user)
|
|
||||||
jafnhar = insert(:user)
|
|
||||||
tridi = insert(:user)
|
|
||||||
|
|
||||||
{:ok, chat_1} = Chat.get_or_create(user.id, har.ap_id)
|
test "it does not return chats with users you blocked", %{conn: conn, user: user} do
|
||||||
{:ok, chat_1} = time_travel(chat_1, -3)
|
recipient = insert(:user)
|
||||||
{:ok, chat_2} = Chat.get_or_create(user.id, jafnhar.ap_id)
|
|
||||||
{:ok, _chat_2} = time_travel(chat_2, -2)
|
|
||||||
{:ok, chat_3} = Chat.get_or_create(user.id, tridi.ap_id)
|
|
||||||
{:ok, chat_3} = time_travel(chat_3, -1)
|
|
||||||
|
|
||||||
# bump the second one
|
{:ok, _} = Chat.get_or_create(user.id, recipient.ap_id)
|
||||||
{:ok, chat_2} = Chat.bump_or_create(user.id, jafnhar.ap_id)
|
|
||||||
|
|
||||||
result =
|
result =
|
||||||
conn
|
conn
|
||||||
|> get("/api/v1/pleroma/chats")
|
|> get(unquote(tested_endpoint))
|
||||||
|> json_response_and_validate_schema(200)
|
|> json_response_and_validate_schema(200)
|
||||||
|
|
||||||
ids = Enum.map(result, & &1["id"])
|
assert length(result) == 1
|
||||||
|
|
||||||
assert ids == [
|
User.block(user, recipient)
|
||||||
chat_2.id |> to_string(),
|
|
||||||
chat_3.id |> to_string(),
|
|
||||||
chat_1.id |> to_string()
|
|
||||||
]
|
|
||||||
end
|
|
||||||
|
|
||||||
test "it is not affected by :restrict_unauthenticated setting (issue #1973)", %{
|
result =
|
||||||
conn: conn,
|
conn
|
||||||
user: user
|
|> get(unquote(tested_endpoint))
|
||||||
} do
|
|> json_response_and_validate_schema(200)
|
||||||
clear_config([:restrict_unauthenticated, :profiles, :local], true)
|
|
||||||
clear_config([:restrict_unauthenticated, :profiles, :remote], true)
|
|
||||||
|
|
||||||
user2 = insert(:user)
|
assert length(result) == 0
|
||||||
user3 = insert(:user, local: false)
|
end
|
||||||
|
|
||||||
{:ok, _chat_12} = Chat.get_or_create(user.id, user2.ap_id)
|
test "it does not return chats with users you muted", %{conn: conn, user: user} do
|
||||||
{:ok, _chat_13} = Chat.get_or_create(user.id, user3.ap_id)
|
recipient = insert(:user)
|
||||||
|
|
||||||
result =
|
{:ok, _} = Chat.get_or_create(user.id, recipient.ap_id)
|
||||||
conn
|
|
||||||
|> get("/api/v1/pleroma/chats")
|
|
||||||
|> json_response_and_validate_schema(200)
|
|
||||||
|
|
||||||
account_ids = Enum.map(result, &get_in(&1, ["account", "id"]))
|
result =
|
||||||
assert Enum.sort(account_ids) == Enum.sort([user2.id, user3.id])
|
conn
|
||||||
|
|> get(unquote(tested_endpoint))
|
||||||
|
|> json_response_and_validate_schema(200)
|
||||||
|
|
||||||
|
assert length(result) == 1
|
||||||
|
|
||||||
|
User.mute(user, recipient)
|
||||||
|
|
||||||
|
result =
|
||||||
|
conn
|
||||||
|
|> get(unquote(tested_endpoint))
|
||||||
|
|> json_response_and_validate_schema(200)
|
||||||
|
|
||||||
|
assert length(result) == 0
|
||||||
|
|
||||||
|
result =
|
||||||
|
conn
|
||||||
|
|> get("#{unquote(tested_endpoint)}?with_muted=true")
|
||||||
|
|> json_response_and_validate_schema(200)
|
||||||
|
|
||||||
|
assert length(result) == 1
|
||||||
|
end
|
||||||
|
|
||||||
|
if tested_endpoint == "/api/v1/pleroma/chats" do
|
||||||
|
test "it returns all chats", %{conn: conn, user: user} do
|
||||||
|
Enum.each(1..30, fn _ ->
|
||||||
|
recipient = insert(:user)
|
||||||
|
{:ok, _} = Chat.get_or_create(user.id, recipient.ap_id)
|
||||||
|
end)
|
||||||
|
|
||||||
|
result =
|
||||||
|
conn
|
||||||
|
|> get(unquote(tested_endpoint))
|
||||||
|
|> json_response_and_validate_schema(200)
|
||||||
|
|
||||||
|
assert length(result) == 30
|
||||||
|
end
|
||||||
|
else
|
||||||
|
test "it paginates chats", %{conn: conn, user: user} do
|
||||||
|
Enum.each(1..30, fn _ ->
|
||||||
|
recipient = insert(:user)
|
||||||
|
{:ok, _} = Chat.get_or_create(user.id, recipient.ap_id)
|
||||||
|
end)
|
||||||
|
|
||||||
|
result =
|
||||||
|
conn
|
||||||
|
|> get(unquote(tested_endpoint))
|
||||||
|
|> json_response_and_validate_schema(200)
|
||||||
|
|
||||||
|
assert length(result) == 20
|
||||||
|
last_id = List.last(result)["id"]
|
||||||
|
|
||||||
|
result =
|
||||||
|
conn
|
||||||
|
|> get(unquote(tested_endpoint) <> "?max_id=#{last_id}")
|
||||||
|
|> json_response_and_validate_schema(200)
|
||||||
|
|
||||||
|
assert length(result) == 10
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
test "it return a list of chats the current user is participating in, in descending order of updates",
|
||||||
|
%{conn: conn, user: user} do
|
||||||
|
har = insert(:user)
|
||||||
|
jafnhar = insert(:user)
|
||||||
|
tridi = insert(:user)
|
||||||
|
|
||||||
|
{:ok, chat_1} = Chat.get_or_create(user.id, har.ap_id)
|
||||||
|
{:ok, chat_1} = time_travel(chat_1, -3)
|
||||||
|
{:ok, chat_2} = Chat.get_or_create(user.id, jafnhar.ap_id)
|
||||||
|
{:ok, _chat_2} = time_travel(chat_2, -2)
|
||||||
|
{:ok, chat_3} = Chat.get_or_create(user.id, tridi.ap_id)
|
||||||
|
{:ok, chat_3} = time_travel(chat_3, -1)
|
||||||
|
|
||||||
|
# bump the second one
|
||||||
|
{:ok, chat_2} = Chat.bump_or_create(user.id, jafnhar.ap_id)
|
||||||
|
|
||||||
|
result =
|
||||||
|
conn
|
||||||
|
|> get(unquote(tested_endpoint))
|
||||||
|
|> json_response_and_validate_schema(200)
|
||||||
|
|
||||||
|
ids = Enum.map(result, & &1["id"])
|
||||||
|
|
||||||
|
assert ids == [
|
||||||
|
chat_2.id |> to_string(),
|
||||||
|
chat_3.id |> to_string(),
|
||||||
|
chat_1.id |> to_string()
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
test "it is not affected by :restrict_unauthenticated setting (issue #1973)", %{
|
||||||
|
conn: conn,
|
||||||
|
user: user
|
||||||
|
} do
|
||||||
|
clear_config([:restrict_unauthenticated, :profiles, :local], true)
|
||||||
|
clear_config([:restrict_unauthenticated, :profiles, :remote], true)
|
||||||
|
|
||||||
|
user2 = insert(:user)
|
||||||
|
user3 = insert(:user, local: false)
|
||||||
|
|
||||||
|
{:ok, _chat_12} = Chat.get_or_create(user.id, user2.ap_id)
|
||||||
|
{:ok, _chat_13} = Chat.get_or_create(user.id, user3.ap_id)
|
||||||
|
|
||||||
|
result =
|
||||||
|
conn
|
||||||
|
|> get(unquote(tested_endpoint))
|
||||||
|
|> json_response_and_validate_schema(200)
|
||||||
|
|
||||||
|
account_ids = Enum.map(result, &get_in(&1, ["account", "id"]))
|
||||||
|
assert Enum.sort(account_ids) == Enum.sort([user2.id, user3.id])
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -13,8 +13,6 @@ defmodule Pleroma.Web.PleromaAPI.EmojiFileControllerTest do
|
||||||
Pleroma.Config.get!([:instance, :static_dir]),
|
Pleroma.Config.get!([:instance, :static_dir]),
|
||||||
"emoji"
|
"emoji"
|
||||||
)
|
)
|
||||||
setup do: clear_config([:auth, :enforce_oauth_admin_scope_usage], false)
|
|
||||||
|
|
||||||
setup do: clear_config([:instance, :public], true)
|
setup do: clear_config([:instance, :public], true)
|
||||||
|
|
||||||
setup do
|
setup do
|
||||||
|
|
|
@ -13,7 +13,6 @@ defmodule Pleroma.Web.PleromaAPI.EmojiPackControllerTest do
|
||||||
Pleroma.Config.get!([:instance, :static_dir]),
|
Pleroma.Config.get!([:instance, :static_dir]),
|
||||||
"emoji"
|
"emoji"
|
||||||
)
|
)
|
||||||
setup do: clear_config([:auth, :enforce_oauth_admin_scope_usage], false)
|
|
||||||
|
|
||||||
setup do: clear_config([:instance, :public], true)
|
setup do: clear_config([:instance, :public], true)
|
||||||
|
|
||||||
|
|
|
@ -169,42 +169,4 @@ test "filters scopes which directly match or are ancestors of supported scopes"
|
||||||
assert f.(["admin:read"], ["write", "admin"]) == ["admin:read"]
|
assert f.(["admin:read"], ["write", "admin"]) == ["admin:read"]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "transform_scopes/2" do
|
|
||||||
setup do: clear_config([:auth, :enforce_oauth_admin_scope_usage])
|
|
||||||
|
|
||||||
setup do
|
|
||||||
{:ok, %{f: &OAuthScopesPlug.transform_scopes/2}}
|
|
||||||
end
|
|
||||||
|
|
||||||
test "with :admin option, prefixes all requested scopes with `admin:` " <>
|
|
||||||
"and [optionally] keeps only prefixed scopes, " <>
|
|
||||||
"depending on `[:auth, :enforce_oauth_admin_scope_usage]` setting",
|
|
||||||
%{f: f} do
|
|
||||||
clear_config([:auth, :enforce_oauth_admin_scope_usage], false)
|
|
||||||
|
|
||||||
assert f.(["read"], %{admin: true}) == ["admin:read", "read"]
|
|
||||||
|
|
||||||
assert f.(["read", "write"], %{admin: true}) == [
|
|
||||||
"admin:read",
|
|
||||||
"read",
|
|
||||||
"admin:write",
|
|
||||||
"write"
|
|
||||||
]
|
|
||||||
|
|
||||||
clear_config([:auth, :enforce_oauth_admin_scope_usage], true)
|
|
||||||
|
|
||||||
assert f.(["read:accounts"], %{admin: true}) == ["admin:read:accounts"]
|
|
||||||
|
|
||||||
assert f.(["read", "write:reports"], %{admin: true}) == [
|
|
||||||
"admin:read",
|
|
||||||
"admin:write:reports"
|
|
||||||
]
|
|
||||||
end
|
|
||||||
|
|
||||||
test "with no supported options, returns unmodified scopes", %{f: f} do
|
|
||||||
assert f.(["read"], %{}) == ["read"]
|
|
||||||
assert f.(["read", "write"], %{}) == ["read", "write"]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue