Merge remote-tracking branch 'remotes/origin/develop' into media-preview-proxy-nostream
# Conflicts: # CHANGELOG.md
This commit is contained in:
commit
a428800405
14
CHANGELOG.md
14
CHANGELOG.md
@ -9,6 +9,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||||||
|
|
||||||
- Renamed `:await_up_timeout` in `:connections_pool` namespace to `:connect_timeout`, old name is deprecated.
|
- Renamed `:await_up_timeout` in `:connections_pool` namespace to `:connect_timeout`, old name is deprecated.
|
||||||
- Renamed `:timeout` in `pools` namespace to `:recv_timeout`, old name is deprecated.
|
- Renamed `:timeout` in `pools` namespace to `:recv_timeout`, old name is deprecated.
|
||||||
|
- The `discoverable` field in the `User` struct will now add a NOINDEX metatag to profile pages when false.
|
||||||
|
- Users with the `discoverable` field set to false will not show up in searches.
|
||||||
- Minimum lifetime for ephmeral activities changed to 10 minutes and made configurable (`:min_lifetime` option).
|
- Minimum lifetime for ephmeral activities changed to 10 minutes and made configurable (`:min_lifetime` option).
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
@ -29,6 +31,12 @@ switched to a new configuration mechanism, however it was not officially removed
|
|||||||
- Welcome Chat messages preventing user registration with MRF Simple Policy applied to the local instance
|
- Welcome Chat messages preventing user registration with MRF Simple Policy applied to the local instance
|
||||||
- Mastodon API: the public timeline returning an error when the `reply_visibility` parameter is set to `self` for an unauthenticated user
|
- Mastodon API: the public timeline returning an error when the `reply_visibility` parameter is set to `self` for an unauthenticated user
|
||||||
|
|
||||||
|
## Unreleased-patch
|
||||||
|
|
||||||
|
### Security
|
||||||
|
|
||||||
|
- Fix most MRF rules either crashing or not being applied to objects passed into the Common Pipeline (ChatMessage, Question, Answer, Audio, Event)
|
||||||
|
|
||||||
## [2.1.1] - 2020-09-08
|
## [2.1.1] - 2020-09-08
|
||||||
|
|
||||||
### Security
|
### Security
|
||||||
@ -44,6 +52,12 @@ switched to a new configuration mechanism, however it was not officially removed
|
|||||||
### Added
|
### Added
|
||||||
- Rich media failure tracking (along with `:failure_backoff` option).
|
- Rich media failure tracking (along with `:failure_backoff` option).
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Admin API Changes</summary>
|
||||||
|
|
||||||
|
- Add `PATCH /api/pleroma/admin/instance_document/:document_name` to modify the Terms of Service and Instance Panel HTML pages via Admin API
|
||||||
|
</details>
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- Default HTTP adapter not respecting pool setting, leading to possible OOM.
|
- Default HTTP adapter not respecting pool setting, leading to possible OOM.
|
||||||
- Fixed uploading webp images when the Exiftool Upload Filter is enabled by skipping them
|
- Fixed uploading webp images when the Exiftool Upload Filter is enabled by skipping them
|
||||||
|
@ -1455,3 +1455,45 @@ Loads json generated from `config/descriptions.exs`.
|
|||||||
"unread": false
|
"unread": false
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## `GET /api/pleroma/admin/instance_document/:document_name`
|
||||||
|
|
||||||
|
### Get an instance document
|
||||||
|
|
||||||
|
- Authentication: required
|
||||||
|
|
||||||
|
- Response:
|
||||||
|
|
||||||
|
Returns the content of the document
|
||||||
|
|
||||||
|
```html
|
||||||
|
<h1>Instance panel</h1>
|
||||||
|
```
|
||||||
|
|
||||||
|
## `PATCH /api/pleroma/admin/instance_document/:document_name`
|
||||||
|
- Params:
|
||||||
|
- `file` (the file to be uploaded, using multipart form data.)
|
||||||
|
|
||||||
|
### Update an instance document
|
||||||
|
|
||||||
|
- Authentication: required
|
||||||
|
|
||||||
|
- Response:
|
||||||
|
|
||||||
|
``` json
|
||||||
|
{
|
||||||
|
"url": "https://example.com/instance/panel.html"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## `DELETE /api/pleroma/admin/instance_document/:document_name`
|
||||||
|
|
||||||
|
### Delete an instance document
|
||||||
|
|
||||||
|
- Response:
|
||||||
|
|
||||||
|
``` json
|
||||||
|
{
|
||||||
|
"url": "https://example.com/instance/panel.html"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
@ -32,7 +32,8 @@ defmodule Mix.Tasks.Pleroma.Config do
|
|||||||
|
|
||||||
@spec migrate_to_db(Path.t() | nil) :: any()
|
@spec migrate_to_db(Path.t() | nil) :: any()
|
||||||
def migrate_to_db(file_path \\ nil) do
|
def migrate_to_db(file_path \\ nil) do
|
||||||
if Pleroma.Config.get([:configurable_from_database]) do
|
with true <- Pleroma.Config.get([:configurable_from_database]),
|
||||||
|
:ok <- Pleroma.Config.DeprecationWarnings.warn() do
|
||||||
config_file =
|
config_file =
|
||||||
if file_path do
|
if file_path do
|
||||||
file_path
|
file_path
|
||||||
@ -46,7 +47,8 @@ defmodule Mix.Tasks.Pleroma.Config do
|
|||||||
|
|
||||||
do_migrate_to_db(config_file)
|
do_migrate_to_db(config_file)
|
||||||
else
|
else
|
||||||
migration_error()
|
:error -> deprecation_error()
|
||||||
|
_ -> migration_error()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -120,6 +122,10 @@ defmodule Mix.Tasks.Pleroma.Config do
|
|||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp deprecation_error do
|
||||||
|
shell_error("Migration is not allowed until all deprecation warnings have been resolved.")
|
||||||
|
end
|
||||||
|
|
||||||
if Code.ensure_loaded?(Config.Reader) do
|
if Code.ensure_loaded?(Config.Reader) do
|
||||||
defp config_header, do: "import Config\r\n\r\n"
|
defp config_header, do: "import Config\r\n\r\n"
|
||||||
defp read_file(config_file), do: Config.Reader.read_imports!(config_file)
|
defp read_file(config_file), do: Config.Reader.read_imports!(config_file)
|
||||||
|
@ -26,6 +26,10 @@ defmodule Pleroma.Config.DeprecationWarnings do
|
|||||||
!!!DEPRECATION WARNING!!!
|
!!!DEPRECATION WARNING!!!
|
||||||
You are using the old configuration mechanism for the hellthread filter. Please check config.md.
|
You are using the old configuration mechanism for the hellthread filter. Please check config.md.
|
||||||
""")
|
""")
|
||||||
|
|
||||||
|
:error
|
||||||
|
else
|
||||||
|
:ok
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -47,17 +51,26 @@ defmodule Pleroma.Config.DeprecationWarnings do
|
|||||||
|
|
||||||
config :pleroma, :mrf_user_allowlist, #{inspect(rewritten, pretty: true)}
|
config :pleroma, :mrf_user_allowlist, #{inspect(rewritten, pretty: true)}
|
||||||
""")
|
""")
|
||||||
|
|
||||||
|
:error
|
||||||
|
else
|
||||||
|
:ok
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def warn do
|
def warn do
|
||||||
check_hellthread_threshold()
|
with :ok <- check_hellthread_threshold(),
|
||||||
mrf_user_allowlist()
|
:ok <- mrf_user_allowlist(),
|
||||||
check_old_mrf_config()
|
:ok <- check_old_mrf_config(),
|
||||||
check_media_proxy_whitelist_config()
|
:ok <- check_media_proxy_whitelist_config(),
|
||||||
check_welcome_message_config()
|
:ok <- check_welcome_message_config(),
|
||||||
check_gun_pool_options()
|
:ok <- check_gun_pool_options(),
|
||||||
check_activity_expiration_config()
|
:ok <- check_activity_expiration_config() do
|
||||||
|
:ok
|
||||||
|
else
|
||||||
|
_ ->
|
||||||
|
:error
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_welcome_message_config do
|
def check_welcome_message_config do
|
||||||
@ -74,6 +87,10 @@ defmodule Pleroma.Config.DeprecationWarnings do
|
|||||||
\n* `config :pleroma, :instance, welcome_user_nickname` is now `config :pleroma, :welcome, :direct_message, :sender_nickname`
|
\n* `config :pleroma, :instance, welcome_user_nickname` is now `config :pleroma, :welcome, :direct_message, :sender_nickname`
|
||||||
\n* `config :pleroma, :instance, welcome_message` is now `config :pleroma, :welcome, :direct_message, :message`
|
\n* `config :pleroma, :instance, welcome_message` is now `config :pleroma, :welcome, :direct_message, :message`
|
||||||
""")
|
""")
|
||||||
|
|
||||||
|
:error
|
||||||
|
else
|
||||||
|
:ok
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -101,8 +118,11 @@ defmodule Pleroma.Config.DeprecationWarnings do
|
|||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
if warning != "" do
|
if warning == "" do
|
||||||
|
:ok
|
||||||
|
else
|
||||||
Logger.warn(warning_preface <> warning)
|
Logger.warn(warning_preface <> warning)
|
||||||
|
:error
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -115,6 +135,10 @@ defmodule Pleroma.Config.DeprecationWarnings do
|
|||||||
!!!DEPRECATION WARNING!!!
|
!!!DEPRECATION WARNING!!!
|
||||||
Your config is using old format (only domain) for MediaProxy whitelist option. Setting should work for now, but you are advised to change format to scheme with port to prevent possible issues later.
|
Your config is using old format (only domain) for MediaProxy whitelist option. Setting should work for now, but you are advised to change format to scheme with port to prevent possible issues later.
|
||||||
""")
|
""")
|
||||||
|
|
||||||
|
:error
|
||||||
|
else
|
||||||
|
:ok
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -157,6 +181,9 @@ defmodule Pleroma.Config.DeprecationWarnings do
|
|||||||
Logger.warn(Enum.join([warning_preface | pool_warnings]))
|
Logger.warn(Enum.join([warning_preface | pool_warnings]))
|
||||||
|
|
||||||
Config.put(:pools, updated_config)
|
Config.put(:pools, updated_config)
|
||||||
|
:error
|
||||||
|
else
|
||||||
|
:ok
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -52,6 +52,7 @@ defmodule Pleroma.User.Search do
|
|||||||
|> base_query(following)
|
|> base_query(following)
|
||||||
|> filter_blocked_user(for_user)
|
|> filter_blocked_user(for_user)
|
||||||
|> filter_invisible_users()
|
|> filter_invisible_users()
|
||||||
|
|> filter_discoverable_users()
|
||||||
|> filter_internal_users()
|
|> filter_internal_users()
|
||||||
|> filter_blocked_domains(for_user)
|
|> filter_blocked_domains(for_user)
|
||||||
|> fts_search(query_string)
|
|> fts_search(query_string)
|
||||||
@ -122,6 +123,10 @@ defmodule Pleroma.User.Search do
|
|||||||
from(q in query, where: q.invisible == false)
|
from(q in query, where: q.invisible == false)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp filter_discoverable_users(query) do
|
||||||
|
from(q in query, where: q.discoverable == true)
|
||||||
|
end
|
||||||
|
|
||||||
defp filter_internal_users(query) do
|
defp filter_internal_users(query) do
|
||||||
from(q in query, where: q.actor_type != "Application")
|
from(q in query, where: q.actor_type != "Application")
|
||||||
end
|
end
|
||||||
|
@ -5,16 +5,34 @@
|
|||||||
defmodule Pleroma.Web.ActivityPub.MRF do
|
defmodule Pleroma.Web.ActivityPub.MRF do
|
||||||
@callback filter(Map.t()) :: {:ok | :reject, Map.t()}
|
@callback filter(Map.t()) :: {:ok | :reject, Map.t()}
|
||||||
|
|
||||||
def filter(policies, %{} = object) do
|
def filter(policies, %{} = message) do
|
||||||
policies
|
policies
|
||||||
|> Enum.reduce({:ok, object}, fn
|
|> Enum.reduce({:ok, message}, fn
|
||||||
policy, {:ok, object} -> policy.filter(object)
|
policy, {:ok, message} -> policy.filter(message)
|
||||||
_, error -> error
|
_, error -> error
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
def filter(%{} = object), do: get_policies() |> filter(object)
|
def filter(%{} = object), do: get_policies() |> filter(object)
|
||||||
|
|
||||||
|
def pipeline_filter(%{} = message, meta) do
|
||||||
|
object = meta[:object_data]
|
||||||
|
ap_id = message["object"]
|
||||||
|
|
||||||
|
if object && ap_id do
|
||||||
|
with {:ok, message} <- filter(Map.put(message, "object", object)) do
|
||||||
|
meta = Keyword.put(meta, :object_data, message["object"])
|
||||||
|
{:ok, Map.put(message, "object", ap_id), meta}
|
||||||
|
else
|
||||||
|
{err, message} -> {err, message, meta}
|
||||||
|
end
|
||||||
|
else
|
||||||
|
{err, message} = filter(message)
|
||||||
|
|
||||||
|
{err, message, meta}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def get_policies do
|
def get_policies do
|
||||||
Pleroma.Config.get([:mrf, :policies], []) |> get_policies()
|
Pleroma.Config.get([:mrf, :policies], []) |> get_policies()
|
||||||
end
|
end
|
||||||
|
@ -20,9 +20,17 @@ defmodule Pleroma.Web.ActivityPub.MRF.KeywordPolicy do
|
|||||||
String.match?(string, pattern)
|
String.match?(string, pattern)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp check_reject(%{"object" => %{"content" => content, "summary" => summary}} = message) do
|
defp object_payload(%{} = object) do
|
||||||
|
[object["content"], object["summary"], object["name"]]
|
||||||
|
|> Enum.filter(& &1)
|
||||||
|
|> Enum.join("\n")
|
||||||
|
end
|
||||||
|
|
||||||
|
defp check_reject(%{"object" => %{} = object} = message) do
|
||||||
|
payload = object_payload(object)
|
||||||
|
|
||||||
if Enum.any?(Pleroma.Config.get([:mrf_keyword, :reject]), fn pattern ->
|
if Enum.any?(Pleroma.Config.get([:mrf_keyword, :reject]), fn pattern ->
|
||||||
string_matches?(content, pattern) or string_matches?(summary, pattern)
|
string_matches?(payload, pattern)
|
||||||
end) do
|
end) do
|
||||||
{:reject, "[KeywordPolicy] Matches with rejected keyword"}
|
{:reject, "[KeywordPolicy] Matches with rejected keyword"}
|
||||||
else
|
else
|
||||||
@ -30,12 +38,12 @@ defmodule Pleroma.Web.ActivityPub.MRF.KeywordPolicy do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defp check_ftl_removal(
|
defp check_ftl_removal(%{"to" => to, "object" => %{} = object} = message) do
|
||||||
%{"to" => to, "object" => %{"content" => content, "summary" => summary}} = message
|
payload = object_payload(object)
|
||||||
) do
|
|
||||||
if Pleroma.Constants.as_public() in to and
|
if Pleroma.Constants.as_public() in to and
|
||||||
Enum.any?(Pleroma.Config.get([:mrf_keyword, :federated_timeline_removal]), fn pattern ->
|
Enum.any?(Pleroma.Config.get([:mrf_keyword, :federated_timeline_removal]), fn pattern ->
|
||||||
string_matches?(content, pattern) or string_matches?(summary, pattern)
|
string_matches?(payload, pattern)
|
||||||
end) do
|
end) do
|
||||||
to = List.delete(to, Pleroma.Constants.as_public())
|
to = List.delete(to, Pleroma.Constants.as_public())
|
||||||
cc = [Pleroma.Constants.as_public() | message["cc"] || []]
|
cc = [Pleroma.Constants.as_public() | message["cc"] || []]
|
||||||
@ -51,35 +59,24 @@ defmodule Pleroma.Web.ActivityPub.MRF.KeywordPolicy do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defp check_replace(%{"object" => %{"content" => content, "summary" => summary}} = message) do
|
defp check_replace(%{"object" => %{} = object} = message) do
|
||||||
content =
|
object =
|
||||||
if is_binary(content) do
|
["content", "name", "summary"]
|
||||||
content
|
|> Enum.filter(fn field -> Map.has_key?(object, field) && object[field] end)
|
||||||
else
|
|> Enum.reduce(object, fn field, object ->
|
||||||
""
|
data =
|
||||||
end
|
|
||||||
|
|
||||||
summary =
|
|
||||||
if is_binary(summary) do
|
|
||||||
summary
|
|
||||||
else
|
|
||||||
""
|
|
||||||
end
|
|
||||||
|
|
||||||
{content, summary} =
|
|
||||||
Enum.reduce(
|
Enum.reduce(
|
||||||
Pleroma.Config.get([:mrf_keyword, :replace]),
|
Pleroma.Config.get([:mrf_keyword, :replace]),
|
||||||
{content, summary},
|
object[field],
|
||||||
fn {pattern, replacement}, {content_acc, summary_acc} ->
|
fn {pat, repl}, acc -> String.replace(acc, pat, repl) end
|
||||||
{String.replace(content_acc, pattern, replacement),
|
|
||||||
String.replace(summary_acc, pattern, replacement)}
|
|
||||||
end
|
|
||||||
)
|
)
|
||||||
|
|
||||||
{:ok,
|
Map.put(object, field, data)
|
||||||
message
|
end)
|
||||||
|> put_in(["object", "content"], content)
|
|
||||||
|> put_in(["object", "summary"], summary)}
|
message = Map.put(message, "object", object)
|
||||||
|
|
||||||
|
{:ok, message}
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
|
@ -28,8 +28,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SubchainPolicy do
|
|||||||
}"
|
}"
|
||||||
)
|
)
|
||||||
|
|
||||||
subchain
|
MRF.filter(subchain, message)
|
||||||
|> MRF.filter(message)
|
|
||||||
else
|
else
|
||||||
_e -> {:ok, message}
|
_e -> {:ok, message}
|
||||||
end
|
end
|
||||||
|
@ -26,13 +26,17 @@ defmodule Pleroma.Web.ActivityPub.Pipeline do
|
|||||||
|
|
||||||
{:error, e} ->
|
{:error, e} ->
|
||||||
{:error, e}
|
{:error, e}
|
||||||
|
|
||||||
|
{:reject, e} ->
|
||||||
|
{:reject, e}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def do_common_pipeline(object, meta) do
|
def do_common_pipeline(object, meta) do
|
||||||
with {_, {:ok, validated_object, meta}} <-
|
with {_, {:ok, validated_object, meta}} <-
|
||||||
{:validate_object, ObjectValidator.validate(object, meta)},
|
{:validate_object, ObjectValidator.validate(object, meta)},
|
||||||
{_, {:ok, mrfd_object}} <- {:mrf_object, MRF.filter(validated_object)},
|
{_, {:ok, mrfd_object, meta}} <-
|
||||||
|
{:mrf_object, MRF.pipeline_filter(validated_object, meta)},
|
||||||
{_, {:ok, activity, meta}} <-
|
{_, {:ok, activity, meta}} <-
|
||||||
{:persist_object, ActivityPub.persist(mrfd_object, meta)},
|
{:persist_object, ActivityPub.persist(mrfd_object, meta)},
|
||||||
{_, {:ok, activity, meta}} <-
|
{_, {:ok, activity, meta}} <-
|
||||||
@ -40,7 +44,7 @@ defmodule Pleroma.Web.ActivityPub.Pipeline do
|
|||||||
{_, {:ok, _}} <- {:federation, maybe_federate(activity, meta)} do
|
{_, {:ok, _}} <- {:federation, maybe_federate(activity, meta)} do
|
||||||
{:ok, activity, meta}
|
{:ok, activity, meta}
|
||||||
else
|
else
|
||||||
{:mrf_object, {:reject, _}} -> {:ok, nil, meta}
|
{:mrf_object, {:reject, message, _}} -> {:reject, message}
|
||||||
e -> {:error, e}
|
e -> {:error, e}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -0,0 +1,41 @@
|
|||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.Web.AdminAPI.InstanceDocumentController do
|
||||||
|
use Pleroma.Web, :controller
|
||||||
|
|
||||||
|
alias Pleroma.Plugs.InstanceStatic
|
||||||
|
alias Pleroma.Plugs.OAuthScopesPlug
|
||||||
|
alias Pleroma.Web.InstanceDocument
|
||||||
|
|
||||||
|
plug(Pleroma.Web.ApiSpec.CastAndValidate)
|
||||||
|
|
||||||
|
action_fallback(Pleroma.Web.AdminAPI.FallbackController)
|
||||||
|
|
||||||
|
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.Admin.InstanceDocumentOperation
|
||||||
|
|
||||||
|
plug(OAuthScopesPlug, %{scopes: ["read"], admin: true} when action == :show)
|
||||||
|
plug(OAuthScopesPlug, %{scopes: ["write"], admin: true} when action in [:update, :delete])
|
||||||
|
|
||||||
|
def show(conn, %{name: document_name}) do
|
||||||
|
with {:ok, url} <- InstanceDocument.get(document_name),
|
||||||
|
{:ok, content} <- File.read(InstanceStatic.file_path(url)) do
|
||||||
|
conn
|
||||||
|
|> put_resp_content_type("text/html")
|
||||||
|
|> send_resp(200, content)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def update(%{body_params: %{file: file}} = conn, %{name: document_name}) do
|
||||||
|
with {:ok, url} <- InstanceDocument.put(document_name, file.path) do
|
||||||
|
json(conn, %{"url" => url})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def delete(conn, %{name: document_name}) do
|
||||||
|
with :ok <- InstanceDocument.delete(document_name) do
|
||||||
|
json(conn, %{})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,115 @@
|
|||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.Web.ApiSpec.Admin.InstanceDocumentOperation do
|
||||||
|
alias OpenApiSpex.Operation
|
||||||
|
alias OpenApiSpex.Schema
|
||||||
|
alias Pleroma.Web.ApiSpec.Helpers
|
||||||
|
alias Pleroma.Web.ApiSpec.Schemas.ApiError
|
||||||
|
|
||||||
|
def open_api_operation(action) do
|
||||||
|
operation = String.to_existing_atom("#{action}_operation")
|
||||||
|
apply(__MODULE__, operation, [])
|
||||||
|
end
|
||||||
|
|
||||||
|
def show_operation do
|
||||||
|
%Operation{
|
||||||
|
tags: ["Admin", "InstanceDocument"],
|
||||||
|
summary: "Get the instance document",
|
||||||
|
operationId: "AdminAPI.InstanceDocumentController.show",
|
||||||
|
security: [%{"oAuth" => ["read"]}],
|
||||||
|
parameters: [
|
||||||
|
Operation.parameter(:name, :path, %Schema{type: :string}, "The document name",
|
||||||
|
required: true
|
||||||
|
)
|
||||||
|
| Helpers.admin_api_params()
|
||||||
|
],
|
||||||
|
responses: %{
|
||||||
|
200 => document_content(),
|
||||||
|
400 => Operation.response("Bad Request", "application/json", ApiError),
|
||||||
|
403 => Operation.response("Forbidden", "application/json", ApiError),
|
||||||
|
404 => Operation.response("Not Found", "application/json", ApiError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_operation do
|
||||||
|
%Operation{
|
||||||
|
tags: ["Admin", "InstanceDocument"],
|
||||||
|
summary: "Update the instance document",
|
||||||
|
operationId: "AdminAPI.InstanceDocumentController.update",
|
||||||
|
security: [%{"oAuth" => ["write"]}],
|
||||||
|
requestBody: Helpers.request_body("Parameters", update_request()),
|
||||||
|
parameters: [
|
||||||
|
Operation.parameter(:name, :path, %Schema{type: :string}, "The document name",
|
||||||
|
required: true
|
||||||
|
)
|
||||||
|
| Helpers.admin_api_params()
|
||||||
|
],
|
||||||
|
responses: %{
|
||||||
|
200 => Operation.response("InstanceDocument", "application/json", instance_document()),
|
||||||
|
400 => Operation.response("Bad Request", "application/json", ApiError),
|
||||||
|
403 => Operation.response("Forbidden", "application/json", ApiError),
|
||||||
|
404 => Operation.response("Not Found", "application/json", ApiError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp update_request do
|
||||||
|
%Schema{
|
||||||
|
title: "UpdateRequest",
|
||||||
|
description: "POST body for uploading the file",
|
||||||
|
type: :object,
|
||||||
|
required: [:file],
|
||||||
|
properties: %{
|
||||||
|
file: %Schema{
|
||||||
|
type: :string,
|
||||||
|
format: :binary,
|
||||||
|
description: "The file to be uploaded, using multipart form data."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def delete_operation do
|
||||||
|
%Operation{
|
||||||
|
tags: ["Admin", "InstanceDocument"],
|
||||||
|
summary: "Get the instance document",
|
||||||
|
operationId: "AdminAPI.InstanceDocumentController.delete",
|
||||||
|
security: [%{"oAuth" => ["write"]}],
|
||||||
|
parameters: [
|
||||||
|
Operation.parameter(:name, :path, %Schema{type: :string}, "The document name",
|
||||||
|
required: true
|
||||||
|
)
|
||||||
|
| Helpers.admin_api_params()
|
||||||
|
],
|
||||||
|
responses: %{
|
||||||
|
200 => Operation.response("InstanceDocument", "application/json", instance_document()),
|
||||||
|
400 => Operation.response("Bad Request", "application/json", ApiError),
|
||||||
|
403 => Operation.response("Forbidden", "application/json", ApiError),
|
||||||
|
404 => Operation.response("Not Found", "application/json", ApiError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp instance_document do
|
||||||
|
%Schema{
|
||||||
|
title: "InstanceDocument",
|
||||||
|
type: :object,
|
||||||
|
properties: %{
|
||||||
|
url: %Schema{type: :string}
|
||||||
|
},
|
||||||
|
example: %{
|
||||||
|
"url" => "https://example.com/static/terms-of-service.html"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp document_content do
|
||||||
|
Operation.response("InstanceDocumentContent", "text/html", %Schema{
|
||||||
|
type: :string,
|
||||||
|
example: "<h1>Instance panel</h1>"
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
@ -184,7 +184,8 @@ defmodule Pleroma.Web.ApiSpec.ChatOperation do
|
|||||||
"application/json",
|
"application/json",
|
||||||
ChatMessage
|
ChatMessage
|
||||||
),
|
),
|
||||||
400 => Operation.response("Bad Request", "application/json", ApiError)
|
400 => Operation.response("Bad Request", "application/json", ApiError),
|
||||||
|
422 => Operation.response("MRF Rejection", "application/json", ApiError)
|
||||||
},
|
},
|
||||||
security: [
|
security: [
|
||||||
%{
|
%{
|
||||||
|
@ -55,7 +55,7 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
|
|||||||
"application/json",
|
"application/json",
|
||||||
%Schema{oneOf: [Status, ScheduledStatus]}
|
%Schema{oneOf: [Status, ScheduledStatus]}
|
||||||
),
|
),
|
||||||
422 => Operation.response("Bad Request", "application/json", ApiError)
|
422 => Operation.response("Bad Request / MRF Rejection", "application/json", ApiError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
@ -48,6 +48,9 @@ defmodule Pleroma.Web.CommonAPI do
|
|||||||
local: true
|
local: true
|
||||||
)} do
|
)} do
|
||||||
{:ok, activity}
|
{:ok, activity}
|
||||||
|
else
|
||||||
|
{:common_pipeline, {:reject, _} = e} -> e
|
||||||
|
e -> e
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
62
lib/pleroma/web/instance_document.ex
Normal file
62
lib/pleroma/web/instance_document.ex
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.Web.InstanceDocument do
|
||||||
|
alias Pleroma.Config
|
||||||
|
alias Pleroma.Web.Endpoint
|
||||||
|
|
||||||
|
@instance_documents %{
|
||||||
|
"terms-of-service" => "/static/terms-of-service.html",
|
||||||
|
"instance-panel" => "/instance/panel.html"
|
||||||
|
}
|
||||||
|
|
||||||
|
@spec get(String.t()) :: {:ok, String.t()} | {:error, atom()}
|
||||||
|
def get(document_name) do
|
||||||
|
case Map.fetch(@instance_documents, document_name) do
|
||||||
|
{:ok, path} -> {:ok, path}
|
||||||
|
_ -> {:error, :not_found}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@spec put(String.t(), String.t()) :: {:ok, String.t()} | {:error, atom()}
|
||||||
|
def put(document_name, origin_path) do
|
||||||
|
with {_, {:ok, destination_path}} <-
|
||||||
|
{:instance_document, Map.fetch(@instance_documents, document_name)},
|
||||||
|
:ok <- put_file(origin_path, destination_path) do
|
||||||
|
{:ok, Path.join(Endpoint.url(), destination_path)}
|
||||||
|
else
|
||||||
|
{:instance_document, :error} -> {:error, :not_found}
|
||||||
|
error -> error
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@spec delete(String.t()) :: :ok | {:error, atom()}
|
||||||
|
def delete(document_name) do
|
||||||
|
with {_, {:ok, path}} <- {:instance_document, Map.fetch(@instance_documents, document_name)},
|
||||||
|
instance_static_dir_path <- instance_static_dir(path),
|
||||||
|
:ok <- File.rm(instance_static_dir_path) do
|
||||||
|
:ok
|
||||||
|
else
|
||||||
|
{:instance_document, :error} -> {:error, :not_found}
|
||||||
|
{:error, :enoent} -> {:error, :not_found}
|
||||||
|
error -> error
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp put_file(origin_path, destination_path) do
|
||||||
|
with destination <- instance_static_dir(destination_path),
|
||||||
|
{_, :ok} <- {:mkdir_p, File.mkdir_p(Path.dirname(destination))},
|
||||||
|
{_, {:ok, _}} <- {:copy, File.copy(origin_path, destination)} do
|
||||||
|
:ok
|
||||||
|
else
|
||||||
|
{error, _} -> {:error, error}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp instance_static_dir(filename) do
|
||||||
|
[:instance, :static_dir]
|
||||||
|
|> Config.get!()
|
||||||
|
|> Path.join(filename)
|
||||||
|
end
|
||||||
|
end
|
@ -10,7 +10,9 @@ defmodule Pleroma.Web.Metadata.Providers.RestrictIndexing do
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def build_tags(%{user: %{local: false}}) do
|
def build_tags(%{user: %{local: true, discoverable: true}}), do: []
|
||||||
|
|
||||||
|
def build_tags(_) do
|
||||||
[
|
[
|
||||||
{:meta,
|
{:meta,
|
||||||
[
|
[
|
||||||
@ -19,7 +21,4 @@ defmodule Pleroma.Web.Metadata.Providers.RestrictIndexing do
|
|||||||
], []}
|
], []}
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
|
||||||
def build_tags(%{user: %{local: true}}), do: []
|
|
||||||
end
|
end
|
||||||
|
@ -90,6 +90,16 @@ defmodule Pleroma.Web.PleromaAPI.ChatController do
|
|||||||
conn
|
conn
|
||||||
|> put_view(MessageReferenceView)
|
|> put_view(MessageReferenceView)
|
||||||
|> render("show.json", chat_message_reference: cm_ref)
|
|> render("show.json", chat_message_reference: cm_ref)
|
||||||
|
else
|
||||||
|
{:reject, message} ->
|
||||||
|
conn
|
||||||
|
|> put_status(:unprocessable_entity)
|
||||||
|
|> json(%{error: message})
|
||||||
|
|
||||||
|
{:error, message} ->
|
||||||
|
conn
|
||||||
|
|> put_status(:bad_request)
|
||||||
|
|> json(%{error: message})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -182,6 +182,10 @@ defmodule Pleroma.Web.Router do
|
|||||||
|
|
||||||
get("/instances/:instance/statuses", AdminAPIController, :list_instance_statuses)
|
get("/instances/:instance/statuses", AdminAPIController, :list_instance_statuses)
|
||||||
|
|
||||||
|
get("/instance_document/:name", InstanceDocumentController, :show)
|
||||||
|
patch("/instance_document/:name", InstanceDocumentController, :update)
|
||||||
|
delete("/instance_document/:name", InstanceDocumentController, :delete)
|
||||||
|
|
||||||
patch("/users/confirm_email", AdminAPIController, :confirm_email)
|
patch("/users/confirm_email", AdminAPIController, :confirm_email)
|
||||||
patch("/users/resend_confirmation_email", AdminAPIController, :resend_confirmation_email)
|
patch("/users/resend_confirmation_email", AdminAPIController, :resend_confirmation_email)
|
||||||
|
|
||||||
|
1
test/fixtures/custom_instance_panel.html
vendored
Normal file
1
test/fixtures/custom_instance_panel.html
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
<h2>Custom instance panel</h2>
|
@ -1,5 +1,8 @@
|
|||||||
{
|
{
|
||||||
"@context": ["https://www.w3.org/ns/activitystreams", "https://w3id.org/security/v1", {
|
"@context": [
|
||||||
|
"https://www.w3.org/ns/activitystreams",
|
||||||
|
"https://w3id.org/security/v1",
|
||||||
|
{
|
||||||
"manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
|
"manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
|
||||||
"sensitive": "as:sensitive",
|
"sensitive": "as:sensitive",
|
||||||
"movedTo": "as:movedTo",
|
"movedTo": "as:movedTo",
|
||||||
@ -14,7 +17,8 @@
|
|||||||
"@id": "as:alsoKnownAs",
|
"@id": "as:alsoKnownAs",
|
||||||
"@type": "@id"
|
"@type": "@id"
|
||||||
}
|
}
|
||||||
}],
|
}
|
||||||
|
],
|
||||||
"id": "http://mastodon.example.org/users/admin",
|
"id": "http://mastodon.example.org/users/admin",
|
||||||
"type": "Person",
|
"type": "Person",
|
||||||
"following": "http://mastodon.example.org/users/admin/following",
|
"following": "http://mastodon.example.org/users/admin/following",
|
||||||
@ -23,6 +27,7 @@
|
|||||||
"outbox": "http://mastodon.example.org/users/admin/outbox",
|
"outbox": "http://mastodon.example.org/users/admin/outbox",
|
||||||
"preferredUsername": "admin",
|
"preferredUsername": "admin",
|
||||||
"name": null,
|
"name": null,
|
||||||
|
"discoverable": "true",
|
||||||
"summary": "\u003cp\u003e\u003c/p\u003e",
|
"summary": "\u003cp\u003e\u003c/p\u003e",
|
||||||
"url": "http://mastodon.example.org/@admin",
|
"url": "http://mastodon.example.org/@admin",
|
||||||
"manuallyApprovesFollowers": false,
|
"manuallyApprovesFollowers": false,
|
||||||
@ -34,7 +39,8 @@
|
|||||||
"owner": "http://mastodon.example.org/users/admin",
|
"owner": "http://mastodon.example.org/users/admin",
|
||||||
"publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtc4Tir+3ADhSNF6VKrtW\nOU32T01w7V0yshmQei38YyiVwVvFu8XOP6ACchkdxbJ+C9mZud8qWaRJKVbFTMUG\nNX4+6Q+FobyuKrwN7CEwhDALZtaN2IPbaPd6uG1B7QhWorrY+yFa8f2TBM3BxnUy\nI4T+bMIZIEYG7KtljCBoQXuTQmGtuffO0UwJksidg2ffCF5Q+K//JfQagJ3UzrR+\nZXbKMJdAw4bCVJYs4Z5EhHYBwQWiXCyMGTd7BGlmMkY6Av7ZqHKC/owp3/0EWDNz\nNqF09Wcpr3y3e8nA10X40MJqp/wR+1xtxp+YGbq/Cj5hZGBG7etFOmIpVBrDOhry\nBwIDAQAB\n-----END PUBLIC KEY-----\n"
|
"publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtc4Tir+3ADhSNF6VKrtW\nOU32T01w7V0yshmQei38YyiVwVvFu8XOP6ACchkdxbJ+C9mZud8qWaRJKVbFTMUG\nNX4+6Q+FobyuKrwN7CEwhDALZtaN2IPbaPd6uG1B7QhWorrY+yFa8f2TBM3BxnUy\nI4T+bMIZIEYG7KtljCBoQXuTQmGtuffO0UwJksidg2ffCF5Q+K//JfQagJ3UzrR+\nZXbKMJdAw4bCVJYs4Z5EhHYBwQWiXCyMGTd7BGlmMkY6Av7ZqHKC/owp3/0EWDNz\nNqF09Wcpr3y3e8nA10X40MJqp/wR+1xtxp+YGbq/Cj5hZGBG7etFOmIpVBrDOhry\nBwIDAQAB\n-----END PUBLIC KEY-----\n"
|
||||||
},
|
},
|
||||||
"attachment": [{
|
"attachment": [
|
||||||
|
{
|
||||||
"type": "PropertyValue",
|
"type": "PropertyValue",
|
||||||
"name": "foo",
|
"name": "foo",
|
||||||
"value": "bar"
|
"value": "bar"
|
||||||
@ -58,5 +64,7 @@
|
|||||||
"mediaType": "image/png",
|
"mediaType": "image/png",
|
||||||
"url": "https://cdn.niu.moe/accounts/headers/000/033/323/original/850b3448fa5fd477.png"
|
"url": "https://cdn.niu.moe/accounts/headers/000/033/323/original/850b3448fa5fd477.png"
|
||||||
},
|
},
|
||||||
"alsoKnownAs": ["http://example.org/users/foo"]
|
"alsoKnownAs": [
|
||||||
|
"http://example.org/users/foo"
|
||||||
|
]
|
||||||
}
|
}
|
@ -8,6 +8,7 @@
|
|||||||
"preferredUsername": "mike",
|
"preferredUsername": "mike",
|
||||||
"name": "Mike Macgirvin (Osada)",
|
"name": "Mike Macgirvin (Osada)",
|
||||||
"updated": "2018-08-29T03:09:11Z",
|
"updated": "2018-08-29T03:09:11Z",
|
||||||
|
"discoverable": "true",
|
||||||
"icon": {
|
"icon": {
|
||||||
"type": "Image",
|
"type": "Image",
|
||||||
"mediaType": "image/jpeg",
|
"mediaType": "image/jpeg",
|
||||||
|
@ -31,6 +31,7 @@ defmodule Pleroma.Factory do
|
|||||||
nickname: sequence(:nickname, &"nick#{&1}"),
|
nickname: sequence(:nickname, &"nick#{&1}"),
|
||||||
password_hash: Pbkdf2.hash_pwd_salt("test"),
|
password_hash: Pbkdf2.hash_pwd_salt("test"),
|
||||||
bio: sequence(:bio, &"Tester Number #{&1}"),
|
bio: sequence(:bio, &"Tester Number #{&1}"),
|
||||||
|
discoverable: true,
|
||||||
last_digest_emailed_at: NaiveDateTime.utc_now(),
|
last_digest_emailed_at: NaiveDateTime.utc_now(),
|
||||||
last_refreshed_at: NaiveDateTime.utc_now(),
|
last_refreshed_at: NaiveDateTime.utc_now(),
|
||||||
notification_settings: %Pleroma.User.NotificationSetting{},
|
notification_settings: %Pleroma.User.NotificationSetting{},
|
||||||
|
@ -40,6 +40,19 @@ defmodule Mix.Tasks.Pleroma.ConfigTest do
|
|||||||
on_exit(fn -> Application.put_env(:quack, :level, initial) end)
|
on_exit(fn -> Application.put_env(:quack, :level, initial) end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@tag capture_log: true
|
||||||
|
test "config migration refused when deprecated settings are found" do
|
||||||
|
clear_config([:media_proxy, :whitelist], ["domain_without_scheme.com"])
|
||||||
|
assert Repo.all(ConfigDB) == []
|
||||||
|
|
||||||
|
Mix.Tasks.Pleroma.Config.migrate_to_db("test/fixtures/config/temp.secret.exs")
|
||||||
|
|
||||||
|
assert_received {:mix_shell, :error, [message]}
|
||||||
|
|
||||||
|
assert message =~
|
||||||
|
"Migration is not allowed until all deprecation warnings have been resolved."
|
||||||
|
end
|
||||||
|
|
||||||
test "filtered settings are migrated to db" do
|
test "filtered settings are migrated to db" do
|
||||||
assert Repo.all(ConfigDB) == []
|
assert Repo.all(ConfigDB) == []
|
||||||
|
|
||||||
|
@ -25,6 +25,14 @@ defmodule Pleroma.UserSearchTest do
|
|||||||
assert found_user.id == user.id
|
assert found_user.id == user.id
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "excludes users when discoverable is false" do
|
||||||
|
insert(:user, %{nickname: "john 3000", discoverable: false})
|
||||||
|
insert(:user, %{nickname: "john 3001"})
|
||||||
|
|
||||||
|
users = User.search("john")
|
||||||
|
assert Enum.count(users) == 1
|
||||||
|
end
|
||||||
|
|
||||||
test "excludes service actors from results" do
|
test "excludes service actors from results" do
|
||||||
insert(:user, actor_type: "Application", nickname: "user1")
|
insert(:user, actor_type: "Application", nickname: "user1")
|
||||||
service = insert(:user, actor_type: "Service", nickname: "user2")
|
service = insert(:user, actor_type: "Service", nickname: "user2")
|
||||||
|
@ -26,7 +26,7 @@ defmodule Pleroma.Web.ActivityPub.PipelineTest do
|
|||||||
{
|
{
|
||||||
Pleroma.Web.ActivityPub.MRF,
|
Pleroma.Web.ActivityPub.MRF,
|
||||||
[],
|
[],
|
||||||
[filter: fn o -> {:ok, o} end]
|
[pipeline_filter: fn o, m -> {:ok, o, m} end]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Pleroma.Web.ActivityPub.ActivityPub,
|
Pleroma.Web.ActivityPub.ActivityPub,
|
||||||
@ -51,7 +51,7 @@ defmodule Pleroma.Web.ActivityPub.PipelineTest do
|
|||||||
Pleroma.Web.ActivityPub.Pipeline.common_pipeline(activity, meta)
|
Pleroma.Web.ActivityPub.Pipeline.common_pipeline(activity, meta)
|
||||||
|
|
||||||
assert_called(Pleroma.Web.ActivityPub.ObjectValidator.validate(activity, meta))
|
assert_called(Pleroma.Web.ActivityPub.ObjectValidator.validate(activity, meta))
|
||||||
assert_called(Pleroma.Web.ActivityPub.MRF.filter(activity))
|
assert_called(Pleroma.Web.ActivityPub.MRF.pipeline_filter(activity, meta))
|
||||||
assert_called(Pleroma.Web.ActivityPub.ActivityPub.persist(activity, meta))
|
assert_called(Pleroma.Web.ActivityPub.ActivityPub.persist(activity, meta))
|
||||||
assert_called(Pleroma.Web.ActivityPub.SideEffects.handle(activity, meta))
|
assert_called(Pleroma.Web.ActivityPub.SideEffects.handle(activity, meta))
|
||||||
refute called(Pleroma.Web.Federator.publish(activity))
|
refute called(Pleroma.Web.Federator.publish(activity))
|
||||||
@ -68,7 +68,7 @@ defmodule Pleroma.Web.ActivityPub.PipelineTest do
|
|||||||
{
|
{
|
||||||
Pleroma.Web.ActivityPub.MRF,
|
Pleroma.Web.ActivityPub.MRF,
|
||||||
[],
|
[],
|
||||||
[filter: fn o -> {:ok, o} end]
|
[pipeline_filter: fn o, m -> {:ok, o, m} end]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Pleroma.Web.ActivityPub.ActivityPub,
|
Pleroma.Web.ActivityPub.ActivityPub,
|
||||||
@ -93,7 +93,7 @@ defmodule Pleroma.Web.ActivityPub.PipelineTest do
|
|||||||
Pleroma.Web.ActivityPub.Pipeline.common_pipeline(activity, meta)
|
Pleroma.Web.ActivityPub.Pipeline.common_pipeline(activity, meta)
|
||||||
|
|
||||||
assert_called(Pleroma.Web.ActivityPub.ObjectValidator.validate(activity, meta))
|
assert_called(Pleroma.Web.ActivityPub.ObjectValidator.validate(activity, meta))
|
||||||
assert_called(Pleroma.Web.ActivityPub.MRF.filter(activity))
|
assert_called(Pleroma.Web.ActivityPub.MRF.pipeline_filter(activity, meta))
|
||||||
assert_called(Pleroma.Web.ActivityPub.ActivityPub.persist(activity, meta))
|
assert_called(Pleroma.Web.ActivityPub.ActivityPub.persist(activity, meta))
|
||||||
assert_called(Pleroma.Web.ActivityPub.SideEffects.handle(activity, meta))
|
assert_called(Pleroma.Web.ActivityPub.SideEffects.handle(activity, meta))
|
||||||
assert_called(Pleroma.Web.Federator.publish(activity))
|
assert_called(Pleroma.Web.Federator.publish(activity))
|
||||||
@ -109,7 +109,7 @@ defmodule Pleroma.Web.ActivityPub.PipelineTest do
|
|||||||
{
|
{
|
||||||
Pleroma.Web.ActivityPub.MRF,
|
Pleroma.Web.ActivityPub.MRF,
|
||||||
[],
|
[],
|
||||||
[filter: fn o -> {:ok, o} end]
|
[pipeline_filter: fn o, m -> {:ok, o, m} end]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Pleroma.Web.ActivityPub.ActivityPub,
|
Pleroma.Web.ActivityPub.ActivityPub,
|
||||||
@ -131,7 +131,7 @@ defmodule Pleroma.Web.ActivityPub.PipelineTest do
|
|||||||
Pleroma.Web.ActivityPub.Pipeline.common_pipeline(activity, meta)
|
Pleroma.Web.ActivityPub.Pipeline.common_pipeline(activity, meta)
|
||||||
|
|
||||||
assert_called(Pleroma.Web.ActivityPub.ObjectValidator.validate(activity, meta))
|
assert_called(Pleroma.Web.ActivityPub.ObjectValidator.validate(activity, meta))
|
||||||
assert_called(Pleroma.Web.ActivityPub.MRF.filter(activity))
|
assert_called(Pleroma.Web.ActivityPub.MRF.pipeline_filter(activity, meta))
|
||||||
assert_called(Pleroma.Web.ActivityPub.ActivityPub.persist(activity, meta))
|
assert_called(Pleroma.Web.ActivityPub.ActivityPub.persist(activity, meta))
|
||||||
assert_called(Pleroma.Web.ActivityPub.SideEffects.handle(activity, meta))
|
assert_called(Pleroma.Web.ActivityPub.SideEffects.handle(activity, meta))
|
||||||
end
|
end
|
||||||
@ -148,7 +148,7 @@ defmodule Pleroma.Web.ActivityPub.PipelineTest do
|
|||||||
{
|
{
|
||||||
Pleroma.Web.ActivityPub.MRF,
|
Pleroma.Web.ActivityPub.MRF,
|
||||||
[],
|
[],
|
||||||
[filter: fn o -> {:ok, o} end]
|
[pipeline_filter: fn o, m -> {:ok, o, m} end]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Pleroma.Web.ActivityPub.ActivityPub,
|
Pleroma.Web.ActivityPub.ActivityPub,
|
||||||
@ -170,7 +170,7 @@ defmodule Pleroma.Web.ActivityPub.PipelineTest do
|
|||||||
Pleroma.Web.ActivityPub.Pipeline.common_pipeline(activity, meta)
|
Pleroma.Web.ActivityPub.Pipeline.common_pipeline(activity, meta)
|
||||||
|
|
||||||
assert_called(Pleroma.Web.ActivityPub.ObjectValidator.validate(activity, meta))
|
assert_called(Pleroma.Web.ActivityPub.ObjectValidator.validate(activity, meta))
|
||||||
assert_called(Pleroma.Web.ActivityPub.MRF.filter(activity))
|
assert_called(Pleroma.Web.ActivityPub.MRF.pipeline_filter(activity, meta))
|
||||||
assert_called(Pleroma.Web.ActivityPub.ActivityPub.persist(activity, meta))
|
assert_called(Pleroma.Web.ActivityPub.ActivityPub.persist(activity, meta))
|
||||||
assert_called(Pleroma.Web.ActivityPub.SideEffects.handle(activity, meta))
|
assert_called(Pleroma.Web.ActivityPub.SideEffects.handle(activity, meta))
|
||||||
end
|
end
|
||||||
|
@ -0,0 +1,106 @@
|
|||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.Web.AdminAPI.InstanceDocumentControllerTest do
|
||||||
|
use Pleroma.Web.ConnCase, async: true
|
||||||
|
import Pleroma.Factory
|
||||||
|
alias Pleroma.Config
|
||||||
|
|
||||||
|
@dir "test/tmp/instance_static"
|
||||||
|
@default_instance_panel ~s(<p>Welcome to <a href="https://pleroma.social" target="_blank">Pleroma!</a></p>)
|
||||||
|
|
||||||
|
setup do
|
||||||
|
File.mkdir_p!(@dir)
|
||||||
|
on_exit(fn -> File.rm_rf(@dir) end)
|
||||||
|
end
|
||||||
|
|
||||||
|
setup do: clear_config([:instance, :static_dir], @dir)
|
||||||
|
|
||||||
|
setup do
|
||||||
|
admin = insert(:user, is_admin: true)
|
||||||
|
token = insert(:oauth_admin_token, user: admin)
|
||||||
|
|
||||||
|
conn =
|
||||||
|
build_conn()
|
||||||
|
|> assign(:user, admin)
|
||||||
|
|> assign(:token, token)
|
||||||
|
|
||||||
|
{:ok, %{admin: admin, token: token, conn: conn}}
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "GET /api/pleroma/admin/instance_document/:name" do
|
||||||
|
test "return the instance document url", %{conn: conn} do
|
||||||
|
conn = get(conn, "/api/pleroma/admin/instance_document/instance-panel")
|
||||||
|
|
||||||
|
assert content = html_response(conn, 200)
|
||||||
|
assert String.contains?(content, @default_instance_panel)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "it returns 403 if requested by a non-admin" do
|
||||||
|
non_admin_user = insert(:user)
|
||||||
|
token = insert(:oauth_token, user: non_admin_user)
|
||||||
|
|
||||||
|
conn =
|
||||||
|
build_conn()
|
||||||
|
|> assign(:user, non_admin_user)
|
||||||
|
|> assign(:token, token)
|
||||||
|
|> get("/api/pleroma/admin/instance_document/instance-panel")
|
||||||
|
|
||||||
|
assert json_response(conn, :forbidden)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "it returns 404 if the instance document with the given name doesn't exist", %{
|
||||||
|
conn: conn
|
||||||
|
} do
|
||||||
|
conn = get(conn, "/api/pleroma/admin/instance_document/1234")
|
||||||
|
|
||||||
|
assert json_response_and_validate_schema(conn, 404)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "PATCH /api/pleroma/admin/instance_document/:name" do
|
||||||
|
test "uploads the instance document", %{conn: conn} do
|
||||||
|
image = %Plug.Upload{
|
||||||
|
content_type: "text/html",
|
||||||
|
path: Path.absname("test/fixtures/custom_instance_panel.html"),
|
||||||
|
filename: "custom_instance_panel.html"
|
||||||
|
}
|
||||||
|
|
||||||
|
conn =
|
||||||
|
conn
|
||||||
|
|> put_req_header("content-type", "multipart/form-data")
|
||||||
|
|> patch("/api/pleroma/admin/instance_document/instance-panel", %{
|
||||||
|
"file" => image
|
||||||
|
})
|
||||||
|
|
||||||
|
assert %{"url" => url} = json_response_and_validate_schema(conn, 200)
|
||||||
|
index = get(build_conn(), url)
|
||||||
|
assert html_response(index, 200) == "<h2>Custom instance panel</h2>"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "DELETE /api/pleroma/admin/instance_document/:name" do
|
||||||
|
test "deletes the instance document", %{conn: conn} do
|
||||||
|
File.mkdir!(@dir <> "/instance/")
|
||||||
|
File.write!(@dir <> "/instance/panel.html", "Custom instance panel")
|
||||||
|
|
||||||
|
conn_resp =
|
||||||
|
conn
|
||||||
|
|> get("/api/pleroma/admin/instance_document/instance-panel")
|
||||||
|
|
||||||
|
assert html_response(conn_resp, 200) == "Custom instance panel"
|
||||||
|
|
||||||
|
conn
|
||||||
|
|> delete("/api/pleroma/admin/instance_document/instance-panel")
|
||||||
|
|> json_response_and_validate_schema(200)
|
||||||
|
|
||||||
|
conn_resp =
|
||||||
|
conn
|
||||||
|
|> get("/api/pleroma/admin/instance_document/instance-panel")
|
||||||
|
|
||||||
|
assert content = html_response(conn_resp, 200)
|
||||||
|
assert String.contains?(content, @default_instance_panel)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -177,5 +177,14 @@ defmodule Pleroma.Web.AdminAPI.SearchTest do
|
|||||||
assert total == 3
|
assert total == 3
|
||||||
assert count == 1
|
assert count == 1
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "it returns non-discoverable users" do
|
||||||
|
insert(:user)
|
||||||
|
insert(:user, discoverable: false)
|
||||||
|
|
||||||
|
{:ok, _results, total} = Search.user()
|
||||||
|
|
||||||
|
assert total == 2
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -217,6 +217,17 @@ defmodule Pleroma.Web.CommonAPITest do
|
|||||||
|
|
||||||
assert message == :content_too_long
|
assert message == :content_too_long
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "it reject messages via MRF" do
|
||||||
|
clear_config([:mrf_keyword, :reject], ["GNO"])
|
||||||
|
clear_config([:mrf, :policies], [Pleroma.Web.ActivityPub.MRF.KeywordPolicy])
|
||||||
|
|
||||||
|
author = insert(:user)
|
||||||
|
recipient = insert(:user)
|
||||||
|
|
||||||
|
assert {:reject, "[KeywordPolicy] Matches with rejected keyword"} ==
|
||||||
|
CommonAPI.post_chat_message(author, recipient, "GNO/Linux")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "unblocking" do
|
describe "unblocking" do
|
||||||
|
@ -69,7 +69,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
|
|||||||
sensitive: false,
|
sensitive: false,
|
||||||
pleroma: %{
|
pleroma: %{
|
||||||
actor_type: "Person",
|
actor_type: "Person",
|
||||||
discoverable: false
|
discoverable: true
|
||||||
},
|
},
|
||||||
fields: []
|
fields: []
|
||||||
},
|
},
|
||||||
@ -167,7 +167,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
|
|||||||
sensitive: false,
|
sensitive: false,
|
||||||
pleroma: %{
|
pleroma: %{
|
||||||
actor_type: "Service",
|
actor_type: "Service",
|
||||||
discoverable: false
|
discoverable: true
|
||||||
},
|
},
|
||||||
fields: []
|
fields: []
|
||||||
},
|
},
|
||||||
|
@ -16,7 +16,14 @@ defmodule Pleroma.Web.MetadataTest do
|
|||||||
end
|
end
|
||||||
|
|
||||||
test "for local user" do
|
test "for local user" do
|
||||||
user = insert(:user)
|
user = insert(:user, discoverable: false)
|
||||||
|
|
||||||
|
assert Pleroma.Web.Metadata.build_tags(%{user: user}) =~
|
||||||
|
"<meta content=\"noindex, noarchive\" name=\"robots\">"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "for local user set to discoverable" do
|
||||||
|
user = insert(:user, discoverable: true)
|
||||||
|
|
||||||
refute Pleroma.Web.Metadata.build_tags(%{user: user}) =~
|
refute Pleroma.Web.Metadata.build_tags(%{user: user}) =~
|
||||||
"<meta content=\"noindex, noarchive\" name=\"robots\">"
|
"<meta content=\"noindex, noarchive\" name=\"robots\">"
|
||||||
@ -24,11 +31,19 @@ defmodule Pleroma.Web.MetadataTest do
|
|||||||
end
|
end
|
||||||
|
|
||||||
describe "no metadata for private instances" do
|
describe "no metadata for private instances" do
|
||||||
test "for local user" do
|
test "for local user set to discoverable" do
|
||||||
clear_config([:instance, :public], false)
|
clear_config([:instance, :public], false)
|
||||||
user = insert(:user, bio: "This is my secret fedi account bio")
|
user = insert(:user, bio: "This is my secret fedi account bio", discoverable: true)
|
||||||
|
|
||||||
assert "" = Pleroma.Web.Metadata.build_tags(%{user: user})
|
assert "" = Pleroma.Web.Metadata.build_tags(%{user: user})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "search exclusion metadata is included" do
|
||||||
|
clear_config([:instance, :public], false)
|
||||||
|
user = insert(:user, bio: "This is my secret fedi account bio", discoverable: false)
|
||||||
|
|
||||||
|
assert ~s(<meta content="noindex, noarchive" name="robots">) ==
|
||||||
|
Pleroma.Web.Metadata.build_tags(%{user: user})
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -14,8 +14,14 @@ defmodule Pleroma.Web.Metadata.Providers.RestrictIndexingTest do
|
|||||||
|
|
||||||
test "for local user" do
|
test "for local user" do
|
||||||
assert Pleroma.Web.Metadata.Providers.RestrictIndexing.build_tags(%{
|
assert Pleroma.Web.Metadata.Providers.RestrictIndexing.build_tags(%{
|
||||||
user: %Pleroma.User{local: true}
|
user: %Pleroma.User{local: true, discoverable: true}
|
||||||
}) == []
|
}) == []
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "for local user when discoverable is false" do
|
||||||
|
assert Pleroma.Web.Metadata.Providers.RestrictIndexing.build_tags(%{
|
||||||
|
user: %Pleroma.User{local: true, discoverable: false}
|
||||||
|
}) == [{:meta, [name: "robots", content: "noindex, noarchive"], []}]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -100,7 +100,7 @@ defmodule Pleroma.Web.PleromaAPI.ChatControllerTest do
|
|||||||
|> post("/api/v1/pleroma/chats/#{chat.id}/messages")
|
|> post("/api/v1/pleroma/chats/#{chat.id}/messages")
|
||||||
|> json_response_and_validate_schema(400)
|
|> json_response_and_validate_schema(400)
|
||||||
|
|
||||||
assert result
|
assert %{"error" => "no_content"} == result
|
||||||
end
|
end
|
||||||
|
|
||||||
test "it works with an attachment", %{conn: conn, user: user} do
|
test "it works with an attachment", %{conn: conn, user: user} do
|
||||||
@ -126,6 +126,23 @@ defmodule Pleroma.Web.PleromaAPI.ChatControllerTest do
|
|||||||
|
|
||||||
assert result["attachment"]
|
assert result["attachment"]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "gets MRF reason when rejected", %{conn: conn, user: user} do
|
||||||
|
clear_config([:mrf_keyword, :reject], ["GNO"])
|
||||||
|
clear_config([:mrf, :policies], [Pleroma.Web.ActivityPub.MRF.KeywordPolicy])
|
||||||
|
|
||||||
|
other_user = insert(:user)
|
||||||
|
|
||||||
|
{:ok, chat} = Chat.get_or_create(user.id, other_user.ap_id)
|
||||||
|
|
||||||
|
result =
|
||||||
|
conn
|
||||||
|
|> put_req_header("content-type", "application/json")
|
||||||
|
|> post("/api/v1/pleroma/chats/#{chat.id}/messages", %{"content" => "GNO/Linux"})
|
||||||
|
|> json_response_and_validate_schema(422)
|
||||||
|
|
||||||
|
assert %{"error" => "[KeywordPolicy] Matches with rejected keyword"} == result
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "DELETE /api/v1/pleroma/chats/:id/messages/:message_id" do
|
describe "DELETE /api/v1/pleroma/chats/:id/messages/:message_id" do
|
||||||
|
Loading…
Reference in New Issue
Block a user