summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLain Soykaf <lain@lain.com>2023-06-11 16:31:20 +0400
committerLain Soykaf <lain@lain.com>2023-06-11 16:31:20 +0400
commit55dd8ef1c799bcfee803e68028af733a697711d1 (patch)
treebea06b9247b2f28aa79b805a7510ecdca76787f3
parent279fd47b486ccfda4537d7a64d553ac261a6fdd8 (diff)
parent16313af7eb1c3b92210e0c0762e74c051bdde5f2 (diff)
Merge branch 'develop' of git.pleroma.social:pleroma/pleroma into pleroma-double_mentions
-rw-r--r--CHANGELOG.md20
-rw-r--r--changelog.d/3126.fix1
-rw-r--r--changelog.d/3831.skip0
-rw-r--r--changelog.d/3880.remove1
-rw-r--r--changelog.d/3884.fix1
-rw-r--r--changelog.d/3885.fix1
-rw-r--r--changelog.d/3891.fix1
-rw-r--r--changelog.d/3893.skip0
-rw-r--r--changelog.d/3896.add1
-rw-r--r--changelog.d/3897.add1
-rw-r--r--changelog.d/3899.skip0
-rw-r--r--changelog.d/3901.security1
-rw-r--r--changelog.d/3902.skip0
-rw-r--r--changelog.d/distro-docs-elixir-1.11.skip0
-rw-r--r--docs/configuration/cheatsheet.md6
-rw-r--r--docs/installation/debian_based_en.md2
-rw-r--r--docs/installation/debian_based_jp.md2
-rw-r--r--lib/pleroma/ecto_type/activity_pub/object_validators/bare_uri.ex23
-rw-r--r--lib/pleroma/upload/filter.ex6
-rw-r--r--lib/pleroma/upload/filter/only_media.ex20
-rw-r--r--lib/pleroma/user.ex13
-rw-r--r--lib/pleroma/web/activity_pub/activity_pub.ex31
-rw-r--r--lib/pleroma/web/activity_pub/object_validators/add_remove_validator.ex3
-rw-r--r--lib/pleroma/web/activity_pub/object_validators/common_fields.ex2
-rw-r--r--lib/pleroma/web/activity_pub/publisher.ex2
-rw-r--r--lib/pleroma/web/activity_pub/transmogrifier.ex42
-rw-r--r--lib/pleroma/web/federator.ex13
-rw-r--r--lib/pleroma/web/media_proxy/media_proxy_controller.ex7
-rw-r--r--lib/pleroma/web/metadata/providers/twitter_card.ex13
-rw-r--r--lib/pleroma/web/plugs/uploaded_media.ex22
-rw-r--r--lib/pleroma/web/preload.ex4
-rw-r--r--lib/pleroma/web/rich_media/parsers/o_embed.ex4
-rw-r--r--lib/pleroma/web/static_fe/static_fe_controller.ex10
-rw-r--r--lib/pleroma/web/streamer.ex46
-rw-r--r--lib/pleroma/workers/transmogrifier_worker.ex18
-rw-r--r--mix.exs9
-rw-r--r--mix.lock3
-rw-r--r--priv/gettext/en_test/LC_MESSAGES/default.po1
-rw-r--r--priv/gettext/en_test/LC_MESSAGES/errors.po1
-rw-r--r--priv/gettext/en_test/LC_MESSAGES/posix_errors.po1
-rw-r--r--priv/gettext/en_test/LC_MESSAGES/static_pages.po4
-rw-r--r--priv/gettext/ru/LC_MESSAGES/errors.po1
-rw-r--r--priv/gettext/zh_Hans/LC_MESSAGES/static_pages.po4
-rw-r--r--priv/repo/migrations/20230504173400_remove_user_ap_enabled.exs13
-rw-r--r--test/pleroma/ecto_type/activity_pub/object_validators/bare_uri_test.ex25
-rw-r--r--test/pleroma/upload/filter/only_media_test.exs32
-rw-r--r--test/pleroma/user_test.exs11
-rw-r--r--test/pleroma/web/activity_pub/activity_pub_controller_test.exs1
-rw-r--r--test/pleroma/web/activity_pub/activity_pub_test.exs1
-rw-r--r--test/pleroma/web/activity_pub/publisher_test.exs15
-rw-r--r--test/pleroma/web/activity_pub/transmogrifier_test.exs64
-rw-r--r--test/pleroma/web/common_api_test.exs2
-rw-r--r--test/pleroma/web/federator_test.exs6
-rw-r--r--test/pleroma/web/media_proxy/media_proxy_controller_test.exs16
-rw-r--r--test/pleroma/web/metadata/providers/twitter_card_test.exs3
-rw-r--r--test/pleroma/web/plugs/uploaded_media_plug_test.exs26
-rw-r--r--test/pleroma/web/rich_media/parser_test.exs4
-rw-r--r--test/pleroma/web/streamer_test.exs77
-rw-r--r--test/support/factory.ex1
59 files changed, 400 insertions, 238 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8d251050c..42a1bbb8f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -18,6 +18,26 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Removed
- BREAKING: Support for passwords generated with `crypt(3)` (Gnu Social migration artifact)
+## 2.5.2
+
+### Security
+- `/proxy` endpoint now sets a Content-Security-Policy (sandbox)
+- WebSocket endpoint now respects unauthenticated restrictions for streams of public posts
+- OEmbed HTML tags are now filtered
+
+### Changed
+- docs: Be more explicit about the level of compatibility of OTP releases
+- Set default background worker timeout to 15 minutes
+
+### Fixed
+- Atom/RSS formatting (HTML truncation, published, missing summary)
+- Remove `static_fe` pipeline for `/users/:nickname/feed`
+- Stop oban from retrying if validating errors occur when processing incoming data
+- Make sure object refetching as used by already received polls follows MRF rules
+
+### Removed
+- BREAKING: Support for passwords generated with `crypt(3)` (Gnu Social migration artifact)
+
## 2.5.1
### Added
diff --git a/changelog.d/3126.fix b/changelog.d/3126.fix
new file mode 100644
index 000000000..91d396c89
--- /dev/null
+++ b/changelog.d/3126.fix
@@ -0,0 +1 @@
+MediaProxy responses now return a sandbox CSP header
diff --git a/changelog.d/3831.skip b/changelog.d/3831.skip
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/changelog.d/3831.skip
diff --git a/changelog.d/3880.remove b/changelog.d/3880.remove
new file mode 100644
index 000000000..113c76c85
--- /dev/null
+++ b/changelog.d/3880.remove
@@ -0,0 +1 @@
+Cleanup OStatus-era user upgrades and ap_enabled indicator \ No newline at end of file
diff --git a/changelog.d/3884.fix b/changelog.d/3884.fix
new file mode 100644
index 000000000..f8dbb2bbf
--- /dev/null
+++ b/changelog.d/3884.fix
@@ -0,0 +1 @@
+Allow non-HTTP(s) URIs in "url" fields for compatibility with "FEP-fffd: Proxy Objects" \ No newline at end of file
diff --git a/changelog.d/3885.fix b/changelog.d/3885.fix
new file mode 100644
index 000000000..c5fbb0ed4
--- /dev/null
+++ b/changelog.d/3885.fix
@@ -0,0 +1 @@
+Fix opengraph and twitter card meta tags
diff --git a/changelog.d/3891.fix b/changelog.d/3891.fix
new file mode 100644
index 000000000..f1fb62d82
--- /dev/null
+++ b/changelog.d/3891.fix
@@ -0,0 +1 @@
+OEmbed HTML tags are now filtered
diff --git a/changelog.d/3893.skip b/changelog.d/3893.skip
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/changelog.d/3893.skip
diff --git a/changelog.d/3896.add b/changelog.d/3896.add
new file mode 100644
index 000000000..e8fde4c8a
--- /dev/null
+++ b/changelog.d/3896.add
@@ -0,0 +1 @@
+Validate Host header for Uploads and return a 302 if the base_url has changed
diff --git a/changelog.d/3897.add b/changelog.d/3897.add
new file mode 100644
index 000000000..5c4402f45
--- /dev/null
+++ b/changelog.d/3897.add
@@ -0,0 +1 @@
+OnlyMedia Upload Filter
diff --git a/changelog.d/3899.skip b/changelog.d/3899.skip
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/changelog.d/3899.skip
diff --git a/changelog.d/3901.security b/changelog.d/3901.security
new file mode 100644
index 000000000..a3d8bd01f
--- /dev/null
+++ b/changelog.d/3901.security
@@ -0,0 +1 @@
+Preload: Make generated JSON html-safe. It already was html safe because it only consists of config data that is base64 encoded, but this will keep it safe it that ever changes.
diff --git a/changelog.d/3902.skip b/changelog.d/3902.skip
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/changelog.d/3902.skip
diff --git a/changelog.d/distro-docs-elixir-1.11.skip b/changelog.d/distro-docs-elixir-1.11.skip
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/changelog.d/distro-docs-elixir-1.11.skip
diff --git a/docs/configuration/cheatsheet.md b/docs/configuration/cheatsheet.md
index 70abe3e0c..1e49a79d0 100644
--- a/docs/configuration/cheatsheet.md
+++ b/docs/configuration/cheatsheet.md
@@ -671,6 +671,12 @@ This filter reads the ImageDescription and iptc:Caption-Abstract fields with Exi
No specific configuration.
+#### Pleroma.Upload.Filter.OnlyMedia
+
+This filter rejects uploads that are not identified with Content-Type matching audio/\*, image/\*, or video/\*
+
+No specific configuration.
+
#### Pleroma.Upload.Filter.Mogrify
* `args`: List of actions for the `mogrify` command like `"strip"` or `["strip", "auto-orient", {"implode", "1"}]`.
diff --git a/docs/installation/debian_based_en.md b/docs/installation/debian_based_en.md
index 4e52b2155..575b8a7ab 100644
--- a/docs/installation/debian_based_en.md
+++ b/docs/installation/debian_based_en.md
@@ -4,7 +4,7 @@
## Installation
-This guide will assume you are on Debian 11 (“bullseye”) or later. This guide should also work with Ubuntu 18.04 (“Bionic Beaver”) and later. It also assumes that you have administrative rights, either as root or a user with [sudo permissions](https://www.digitalocean.com/community/tutorials/how-to-add-delete-and-grant-sudo-privileges-to-users-on-a-debian-vps). If you want to run this guide with root, ignore the `sudo` at the beginning of the lines, unless it calls a user like `sudo -Hu pleroma`; in this case, use `su <username> -s $SHELL -c 'command'` instead.
+This guide will assume you are on Debian 12 (“bookworm”) or later. This guide should also work with Ubuntu 22.04 (“jammy”) and later. It also assumes that you have administrative rights, either as root or a user with [sudo permissions](https://www.digitalocean.com/community/tutorials/how-to-add-delete-and-grant-sudo-privileges-to-users-on-a-debian-vps). If you want to run this guide with root, ignore the `sudo` at the beginning of the lines, unless it calls a user like `sudo -Hu pleroma`; in this case, use `su <username> -s $SHELL -c 'command'` instead.
{! backend/installation/generic_dependencies.include !}
diff --git a/docs/installation/debian_based_jp.md b/docs/installation/debian_based_jp.md
index 3736e857f..695e7bb7d 100644
--- a/docs/installation/debian_based_jp.md
+++ b/docs/installation/debian_based_jp.md
@@ -5,7 +5,7 @@
## インストール
-このガイドはDebian Stretchを利用することを想定しています。Ubuntu 16.04や18.04でもおそらく動作します。また、ユーザはrootもしくはsudoにより管理者権限を持っていることを前提とします。もし、以下の操作をrootユーザで行う場合は、 `sudo` を無視してください。ただし、`sudo -Hu pleroma` のようにユーザを指定している場合には `su <username> -s $SHELL -c 'command'` を代わりに使ってください。
+このガイドはDebian Bookwormを利用することを想定しています。Ubuntu 22.04でもおそらく動作します。また、ユーザはrootもしくはsudoにより管理者権限を持っていることを前提とします。もし、以下の操作をrootユーザで行う場合は、 `sudo` を無視してください。ただし、`sudo -Hu pleroma` のようにユーザを指定している場合には `su <username> -s $SHELL -c 'command'` を代わりに使ってください。
### 必要なソフトウェア
diff --git a/lib/pleroma/ecto_type/activity_pub/object_validators/bare_uri.ex b/lib/pleroma/ecto_type/activity_pub/object_validators/bare_uri.ex
new file mode 100644
index 000000000..1038296e7
--- /dev/null
+++ b/lib/pleroma/ecto_type/activity_pub/object_validators/bare_uri.ex
@@ -0,0 +1,23 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2023 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.EctoType.ActivityPub.ObjectValidators.BareUri do
+ use Ecto.Type
+
+ def type, do: :string
+
+ def cast(uri) when is_binary(uri) do
+ case URI.parse(uri) do
+ %URI{scheme: nil} -> :error
+ %URI{} -> {:ok, uri}
+ _ -> :error
+ end
+ end
+
+ def cast(_), do: :error
+
+ def dump(data), do: {:ok, data}
+
+ def load(data), do: {:ok, data}
+end
diff --git a/lib/pleroma/upload/filter.ex b/lib/pleroma/upload/filter.ex
index 717f06621..809bc6e70 100644
--- a/lib/pleroma/upload/filter.ex
+++ b/lib/pleroma/upload/filter.ex
@@ -38,9 +38,9 @@ defmodule Pleroma.Upload.Filter do
{:ok, :noop} ->
filter(rest, upload)
- error ->
- Logger.error("#{__MODULE__}: Filter #{filter} failed: #{inspect(error)}")
- error
+ {:error, e} ->
+ Logger.error("#{__MODULE__}: Filter #{filter} failed: #{inspect(e)}")
+ {:error, e}
end
end
end
diff --git a/lib/pleroma/upload/filter/only_media.ex b/lib/pleroma/upload/filter/only_media.ex
new file mode 100644
index 000000000..a9caeba67
--- /dev/null
+++ b/lib/pleroma/upload/filter/only_media.ex
@@ -0,0 +1,20 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2023 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Upload.Filter.OnlyMedia do
+ @behaviour Pleroma.Upload.Filter
+ alias Pleroma.Upload
+
+ def filter(%Upload{content_type: content_type}) do
+ [type, _subtype] = String.split(content_type, "/")
+
+ if type in ["image", "video", "audio"] do
+ {:ok, :noop}
+ else
+ {:error, "Disallowed content-type: #{content_type}"}
+ end
+ end
+
+ def filter(_), do: {:ok, :noop}
+end
diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex
index f6e30555c..ce125d608 100644
--- a/lib/pleroma/user.ex
+++ b/lib/pleroma/user.ex
@@ -124,7 +124,6 @@ defmodule Pleroma.User do
field(:domain_blocks, {:array, :string}, default: [])
field(:is_active, :boolean, default: true)
field(:no_rich_text, :boolean, default: false)
- field(:ap_enabled, :boolean, default: false)
field(:is_moderator, :boolean, default: false)
field(:is_admin, :boolean, default: false)
field(:show_role, :boolean, default: true)
@@ -488,7 +487,6 @@ defmodule Pleroma.User do
:nickname,
:public_key,
:avatar,
- :ap_enabled,
:banner,
:is_locked,
:last_refreshed_at,
@@ -1061,11 +1059,7 @@ defmodule Pleroma.User do
end
def maybe_direct_follow(%User{} = follower, %User{} = followed) do
- if not ap_enabled?(followed) do
- follow(follower, followed)
- else
- {:ok, follower, followed}
- end
+ {:ok, follower, followed}
end
@doc "A mass follow for local users. Respects blocks in both directions but does not create activities."
@@ -1898,7 +1892,6 @@ defmodule Pleroma.User do
confirmation_token: nil,
domain_blocks: [],
is_active: false,
- ap_enabled: false,
is_moderator: false,
is_admin: false,
mascot: nil,
@@ -2151,10 +2144,6 @@ defmodule Pleroma.User do
end
end
- def ap_enabled?(%User{local: true}), do: true
- def ap_enabled?(%User{ap_enabled: ap_enabled}), do: ap_enabled
- def ap_enabled?(_), do: false
-
@doc "Gets or fetch a user by uri or nickname."
@spec get_or_fetch(String.t()) :: {:ok, User.t()} | {:error, String.t()}
def get_or_fetch("http://" <> _host = uri), do: get_or_fetch_by_ap_id(uri)
diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex
index f22756015..1a10aef1d 100644
--- a/lib/pleroma/web/activity_pub/activity_pub.ex
+++ b/lib/pleroma/web/activity_pub/activity_pub.ex
@@ -1547,7 +1547,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
%{
ap_id: data["id"],
uri: get_actor_url(data["url"]),
- ap_enabled: true,
banner: normalize_image(data["image"]),
fields: fields,
emoji: emojis,
@@ -1668,7 +1667,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
end
end
- def fetch_and_prepare_user_from_ap_id(ap_id, additional \\ []) do
+ defp fetch_and_prepare_user_from_ap_id(ap_id, additional) do
with {:ok, data} <- Fetcher.fetch_and_contain_remote_object_from_id(ap_id),
{:ok, data} <- user_data_from_user_object(data, additional) do
{:ok, maybe_update_follow_information(data)}
@@ -1751,24 +1750,20 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
def make_user_from_ap_id(ap_id, additional \\ []) do
user = User.get_cached_by_ap_id(ap_id)
- if user && !User.ap_enabled?(user) do
- Transmogrifier.upgrade_user_from_ap_id(ap_id)
- else
- with {:ok, data} <- fetch_and_prepare_user_from_ap_id(ap_id, additional) do
- {:ok, _pid} = Task.start(fn -> pinned_fetch_task(data) end)
+ with {:ok, data} <- fetch_and_prepare_user_from_ap_id(ap_id, additional) do
+ {:ok, _pid} = Task.start(fn -> pinned_fetch_task(data) end)
- if user do
- user
- |> User.remote_user_changeset(data)
- |> User.update_and_set_cache()
- else
- maybe_handle_clashing_nickname(data)
+ if user do
+ user
+ |> User.remote_user_changeset(data)
+ |> User.update_and_set_cache()
+ else
+ maybe_handle_clashing_nickname(data)
- data
- |> User.remote_user_changeset()
- |> Repo.insert()
- |> User.set_cache()
- end
+ data
+ |> User.remote_user_changeset()
+ |> Repo.insert()
+ |> User.set_cache()
end
end
end
diff --git a/lib/pleroma/web/activity_pub/object_validators/add_remove_validator.ex b/lib/pleroma/web/activity_pub/object_validators/add_remove_validator.ex
index 5202db7f1..db3259550 100644
--- a/lib/pleroma/web/activity_pub/object_validators/add_remove_validator.ex
+++ b/lib/pleroma/web/activity_pub/object_validators/add_remove_validator.ex
@@ -73,6 +73,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AddRemoveValidator do
end
defp maybe_refetch_user(%User{ap_id: ap_id}) do
- Pleroma.Web.ActivityPub.Transmogrifier.upgrade_user_from_ap_id(ap_id)
+ # Maybe it could use User.get_or_fetch_by_ap_id to avoid refreshing too often
+ User.fetch_by_ap_id(ap_id)
end
end
diff --git a/lib/pleroma/web/activity_pub/object_validators/common_fields.ex b/lib/pleroma/web/activity_pub/object_validators/common_fields.ex
index 7b60c139a..d580208df 100644
--- a/lib/pleroma/web/activity_pub/object_validators/common_fields.ex
+++ b/lib/pleroma/web/activity_pub/object_validators/common_fields.ex
@@ -58,7 +58,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CommonFields do
field(:like_count, :integer, default: 0)
field(:announcement_count, :integer, default: 0)
field(:inReplyTo, ObjectValidators.ObjectID)
- field(:url, ObjectValidators.Uri)
+ field(:url, ObjectValidators.BareUri)
field(:likes, {:array, ObjectValidators.ObjectID}, default: [])
field(:announcements, {:array, ObjectValidators.ObjectID}, default: [])
diff --git a/lib/pleroma/web/activity_pub/publisher.ex b/lib/pleroma/web/activity_pub/publisher.ex
index 6c1ba76a3..af6aa0781 100644
--- a/lib/pleroma/web/activity_pub/publisher.ex
+++ b/lib/pleroma/web/activity_pub/publisher.ex
@@ -199,7 +199,6 @@ defmodule Pleroma.Web.ActivityPub.Publisher do
inboxes =
recipients
- |> Enum.filter(&User.ap_enabled?/1)
|> Enum.map(fn actor -> actor.inbox end)
|> Enum.filter(fn inbox -> should_federate?(inbox, public) end)
|> Instances.filter_reachable()
@@ -241,7 +240,6 @@ defmodule Pleroma.Web.ActivityPub.Publisher do
json = Jason.encode!(data)
recipients(actor, activity)
- |> Enum.filter(fn user -> User.ap_enabled?(user) end)
|> Enum.map(fn %User{} = user ->
determine_inbox(activity, user)
end)
diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex
index 3141f8437..0e6c429f9 100644
--- a/lib/pleroma/web/activity_pub/transmogrifier.ex
+++ b/lib/pleroma/web/activity_pub/transmogrifier.ex
@@ -20,7 +20,6 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
alias Pleroma.Web.ActivityPub.Utils
alias Pleroma.Web.ActivityPub.Visibility
alias Pleroma.Web.Federator
- alias Pleroma.Workers.TransmogrifierWorker
import Ecto.Query
@@ -946,47 +945,6 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
defp strip_internal_tags(object), do: object
- def perform(:user_upgrade, user) do
- # we pass a fake user so that the followers collection is stripped away
- old_follower_address = User.ap_followers(%User{nickname: user.nickname})
-
- from(
- a in Activity,
- where: ^old_follower_address in a.recipients,
- update: [
- set: [
- recipients:
- fragment(
- "array_replace(?,?,?)",
- a.recipients,
- ^old_follower_address,
- ^user.follower_address
- )
- ]
- ]
- )
- |> Repo.update_all([])
- end
-
- def upgrade_user_from_ap_id(ap_id) do
- with %User{local: false} = user <- User.get_cached_by_ap_id(ap_id),
- {:ok, data} <- ActivityPub.fetch_and_prepare_user_from_ap_id(ap_id),
- {:ok, user} <- update_user(user, data) do
- {:ok, _pid} = Task.start(fn -> ActivityPub.pinned_fetch_task(user) end)
- TransmogrifierWorker.enqueue("user_upgrade", %{"user_id" => user.id})
- {:ok, user}
- else
- %User{} = user -> {:ok, user}
- e -> e
- end
- end
-
- defp update_user(user, data) do
- user
- |> User.remote_user_changeset(data)
- |> User.update_and_set_cache()
- end
-
def maybe_fix_user_url(%{"url" => url} = data) when is_map(url) do
Map.put(data, "url", url["href"])
end
diff --git a/lib/pleroma/web/federator.ex b/lib/pleroma/web/federator.ex
index 318b6cb11..84b77cda1 100644
--- a/lib/pleroma/web/federator.ex
+++ b/lib/pleroma/web/federator.ex
@@ -6,7 +6,6 @@ defmodule Pleroma.Web.Federator do
alias Pleroma.Activity
alias Pleroma.Object.Containment
alias Pleroma.User
- alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.Transmogrifier
alias Pleroma.Web.ActivityPub.Utils
alias Pleroma.Web.Federator.Publisher
@@ -80,7 +79,7 @@ defmodule Pleroma.Web.Federator do
# NOTE: we use the actor ID to do the containment, this is fine because an
# actor shouldn't be acting on objects outside their own AP server.
- with {_, {:ok, _user}} <- {:actor, ap_enabled_actor(actor)},
+ with {_, {:ok, _user}} <- {:actor, User.get_or_fetch_by_ap_id(actor)},
nil <- Activity.normalize(params["id"]),
{_, :ok} <-
{:correct_origin?, Containment.contain_origin_from_id(actor, params)},
@@ -110,14 +109,4 @@ defmodule Pleroma.Web.Federator do
{:error, e}
end
end
-
- def ap_enabled_actor(id) do
- user = User.get_cached_by_ap_id(id)
-
- if User.ap_enabled?(user) do
- {:ok, user}
- else
- ActivityPub.make_user_from_ap_id(id)
- end
- end
end
diff --git a/lib/pleroma/web/media_proxy/media_proxy_controller.ex b/lib/pleroma/web/media_proxy/media_proxy_controller.ex
index d2ad62c13..bda5b36ed 100644
--- a/lib/pleroma/web/media_proxy/media_proxy_controller.ex
+++ b/lib/pleroma/web/media_proxy/media_proxy_controller.ex
@@ -12,6 +12,8 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyController do
alias Pleroma.Web.MediaProxy
alias Plug.Conn
+ plug(:sandbox)
+
def remote(conn, %{"sig" => sig64, "url" => url64}) do
with {_, true} <- {:enabled, MediaProxy.enabled?()},
{:ok, url} <- MediaProxy.decode_url(sig64, url64),
@@ -202,4 +204,9 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyController do
defp media_proxy_opts do
Config.get([:media_proxy, :proxy_opts], [])
end
+
+ defp sandbox(conn, _params) do
+ conn
+ |> merge_resp_headers([{"content-security-policy", "sandbox;"}])
+ end
end
diff --git a/lib/pleroma/web/metadata/providers/twitter_card.ex b/lib/pleroma/web/metadata/providers/twitter_card.ex
index 2dac22ee2..426022c65 100644
--- a/lib/pleroma/web/metadata/providers/twitter_card.ex
+++ b/lib/pleroma/web/metadata/providers/twitter_card.ex
@@ -76,9 +76,10 @@ defmodule Pleroma.Web.Metadata.Providers.TwitterCard do
{:meta, [name: "twitter:card", content: "summary_large_image"], []},
{:meta,
[
- name: "twitter:player",
+ name: "twitter:image",
content: MediaProxy.url(url["href"])
- ], []}
+ ], []},
+ {:meta, [name: "twitter:image:alt", content: truncate(attachment["name"])], []}
| acc
]
|> maybe_add_dimensions(url)
@@ -130,4 +131,12 @@ defmodule Pleroma.Web.Metadata.Providers.TwitterCard do
metadata
end
end
+
+ defp truncate(nil), do: ""
+
+ defp truncate(text) do
+ # truncate to 420 characters
+ # see https://developer.twitter.com/en/docs/twitter-for-websites/cards/overview/markup
+ Pleroma.Formatter.truncate(text, 420)
+ end
end
diff --git a/lib/pleroma/web/plugs/uploaded_media.ex b/lib/pleroma/web/plugs/uploaded_media.ex
index 8b3bc9acb..9dd5eb239 100644
--- a/lib/pleroma/web/plugs/uploaded_media.ex
+++ b/lib/pleroma/web/plugs/uploaded_media.ex
@@ -46,12 +46,32 @@ defmodule Pleroma.Web.Plugs.UploadedMedia do
config = Pleroma.Config.get(Pleroma.Upload)
- with uploader <- Keyword.fetch!(config, :uploader),
+ %{scheme: media_scheme, host: media_host, port: media_port} =
+ Pleroma.Upload.base_url() |> URI.parse()
+
+ with {:valid_host, true} <- {:valid_host, match?(^media_host, conn.host)},
+ uploader <- Keyword.fetch!(config, :uploader),
proxy_remote = Keyword.get(config, :proxy_remote, false),
{:ok, get_method} <- uploader.get_file(file),
false <- media_is_banned(conn, get_method) do
get_media(conn, get_method, proxy_remote, opts)
else
+ {:valid_host, false} ->
+ redirect_url =
+ %URI{
+ scheme: media_scheme,
+ host: media_host,
+ port: media_port,
+ path: conn.request_path,
+ query: conn.query_string
+ }
+ |> URI.to_string()
+ |> String.trim_trailing("?")
+
+ conn
+ |> Phoenix.Controller.redirect(external: redirect_url)
+ |> halt()
+
_ ->
conn
|> send_resp(:internal_server_error, dgettext("errors", "Failed"))
diff --git a/lib/pleroma/web/preload.ex b/lib/pleroma/web/preload.ex
index 4485383f9..6a4a8885e 100644
--- a/lib/pleroma/web/preload.ex
+++ b/lib/pleroma/web/preload.ex
@@ -11,7 +11,7 @@ defmodule Pleroma.Web.Preload do
terms =
params
|> parser.generate_terms()
- |> Enum.map(fn {k, v} -> {k, Base.encode64(Jason.encode!(v))} end)
+ |> Enum.map(fn {k, v} -> {k, Base.encode64(Jason.encode!(v, escape: :html_safe))} end)
|> Enum.into(%{})
Map.merge(acc, terms)
@@ -19,7 +19,7 @@ defmodule Pleroma.Web.Preload do
rendered_html =
preload_data
- |> Jason.encode!()
+ |> Jason.encode!(escape: :html_safe)
|> build_script_tag()
|> HTML.safe_to_string()
diff --git a/lib/pleroma/web/rich_media/parsers/o_embed.ex b/lib/pleroma/web/rich_media/parsers/o_embed.ex
index 75318d9c7..0f303176c 100644
--- a/lib/pleroma/web/rich_media/parsers/o_embed.ex
+++ b/lib/pleroma/web/rich_media/parsers/o_embed.ex
@@ -6,8 +6,8 @@ defmodule Pleroma.Web.RichMedia.Parsers.OEmbed do
def parse(html, _data) do
with elements = [_ | _] <- get_discovery_data(html),
oembed_url when is_binary(oembed_url) <- get_oembed_url(elements),
- {:ok, oembed_data} <- get_oembed_data(oembed_url) do
- oembed_data
+ {:ok, oembed_data = %{"html" => html}} <- get_oembed_data(oembed_url) do
+ %{oembed_data | "html" => Pleroma.HTML.filter_tags(html)}
else
_e -> %{}
end
diff --git a/lib/pleroma/web/static_fe/static_fe_controller.ex b/lib/pleroma/web/static_fe/static_fe_controller.ex
index 97c41c6f9..8019a218a 100644
--- a/lib/pleroma/web/static_fe/static_fe_controller.ex
+++ b/lib/pleroma/web/static_fe/static_fe_controller.ex
@@ -25,7 +25,15 @@ defmodule Pleroma.Web.StaticFE.StaticFEController do
true <- Visibility.is_public?(activity.object),
{_, true} <- {:visible?, Visibility.visible_for_user?(activity, _reading_user = nil)},
%User{} = user <- User.get_by_ap_id(activity.object.data["actor"]) do
- meta = Metadata.build_tags(%{activity_id: notice_id, object: activity.object, user: user})
+ url = Helpers.url(conn) <> conn.request_path
+
+ meta =
+ Metadata.build_tags(%{
+ activity_id: notice_id,
+ object: activity.object,
+ user: user,
+ url: url
+ })
timeline =
activity.object.data["context"]
diff --git a/lib/pleroma/web/streamer.ex b/lib/pleroma/web/streamer.ex
index 3c0da5c27..b9a04cc76 100644
--- a/lib/pleroma/web/streamer.ex
+++ b/lib/pleroma/web/streamer.ex
@@ -25,6 +25,7 @@ defmodule Pleroma.Web.Streamer do
def registry, do: @registry
@public_streams ["public", "public:local", "public:media", "public:local:media"]
+ @local_streams ["public:local", "public:local:media"]
@user_streams ["user", "user:notification", "direct", "user:pleroma_chat"]
@doc "Expands and authorizes a stream, and registers the process for streaming."
@@ -41,14 +42,37 @@ defmodule Pleroma.Web.Streamer do
end
end
+ defp can_access_stream(user, oauth_token, kind) do
+ with {_, true} <- {:restrict?, Config.restrict_unauthenticated_access?(:timelines, kind)},
+ {_, %User{id: user_id}, %Token{user_id: user_id}} <- {:user, user, oauth_token},
+ {_, true} <-
+ {:scopes,
+ OAuthScopesPlug.filter_descendants(["read:statuses"], oauth_token.scopes) != []} do
+ true
+ else
+ {:restrict?, _} ->
+ true
+
+ _ ->
+ false
+ end
+ end
+
@doc "Expand and authorizes a stream"
@spec get_topic(stream :: String.t(), User.t() | nil, Token.t() | nil, Map.t()) ::
{:ok, topic :: String.t()} | {:error, :bad_topic}
def get_topic(stream, user, oauth_token, params \\ %{})
- # Allow all public steams.
- def get_topic(stream, _user, _oauth_token, _params) when stream in @public_streams do
- {:ok, stream}
+ # Allow all public steams if the instance allows unauthenticated access.
+ # Otherwise, only allow users with valid oauth tokens.
+ def get_topic(stream, user, oauth_token, _params) when stream in @public_streams do
+ kind = if stream in @local_streams, do: :local, else: :federated
+
+ if can_access_stream(user, oauth_token, kind) do
+ {:ok, stream}
+ else
+ {:error, :unauthorized}
+ end
end
# Allow all hashtags streams.
@@ -57,12 +81,20 @@ defmodule Pleroma.Web.Streamer do
end
# Allow remote instance streams.
- def get_topic("public:remote", _user, _oauth_token, %{"instance" => instance} = _params) do
- {:ok, "public:remote:" <> instance}
+ def get_topic("public:remote", user, oauth_token, %{"instance" => instance} = _params) do
+ if can_access_stream(user, oauth_token, :federated) do
+ {:ok, "public:remote:" <> instance}
+ else
+ {:error, :unauthorized}
+ end
end
- def get_topic("public:remote:media", _user, _oauth_token, %{"instance" => instance} = _params) do
- {:ok, "public:remote:media:" <> instance}
+ def get_topic("public:remote:media", user, oauth_token, %{"instance" => instance} = _params) do
+ if can_access_stream(user, oauth_token, :federated) do
+ {:ok, "public:remote:media:" <> instance}
+ else
+ {:error, :unauthorized}
+ end
end
# Expand user streams.
diff --git a/lib/pleroma/workers/transmogrifier_worker.ex b/lib/pleroma/workers/transmogrifier_worker.ex
deleted file mode 100644
index 1f3f5385e..000000000
--- a/lib/pleroma/workers/transmogrifier_worker.ex
+++ /dev/null
@@ -1,18 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Workers.TransmogrifierWorker do
- alias Pleroma.User
-
- use Pleroma.Workers.WorkerHelper, queue: "transmogrifier"
-
- @impl Oban.Worker
- def perform(%Job{args: %{"op" => "user_upgrade", "user_id" => user_id}}) do
- user = User.get_cached_by_id(user_id)
- Pleroma.Web.ActivityPub.Transmogrifier.perform(:user_upgrade, user)
- end
-
- @impl Oban.Worker
- def timeout(_job), do: :timer.seconds(5)
-end
diff --git a/mix.exs b/mix.exs
index afce46d22..62ac1c1a0 100644
--- a/mix.exs
+++ b/mix.exs
@@ -4,10 +4,10 @@ defmodule Pleroma.Mixfile do
def project do
[
app: :pleroma,
- version: version("2.5.51"),
+ version: version("2.5.52"),
elixir: "~> 1.11",
elixirc_paths: elixirc_paths(Mix.env()),
- compilers: [:phoenix, :gettext] ++ Mix.compilers(),
+ compilers: [:phoenix] ++ Mix.compilers(),
elixirc_options: [warnings_as_errors: warnings_as_errors()],
xref: [exclude: [:eldap]],
start_permanent: Mix.env() == :prod,
@@ -127,10 +127,7 @@ defmodule Pleroma.Mixfile do
{:plug_cowboy, "~> 2.3"},
# oban 2.14 requires Elixir 1.12+
{:oban, "~> 2.13.4"},
- {:gettext,
- git: "https://github.com/tusooa/gettext.git",
- ref: "72fb2496b6c5280ed911bdc3756890e7f38a4808",
- override: true},
+ {:gettext, "~> 0.20"},
{:bcrypt_elixir, "~> 2.2"},
{:trailing_format_plug, "~> 0.0.7"},
{:fast_sanitize, "~> 0.2.0"},
diff --git a/mix.lock b/mix.lock
index 43012a58e..b6938f44b 100644
--- a/mix.lock
+++ b/mix.lock
@@ -42,6 +42,7 @@
"ex_doc": {:hex, :ex_doc, "0.29.4", "6257ecbb20c7396b1fe5accd55b7b0d23f44b6aa18017b415cb4c2b91d997729", [:mix], [{:earmark_parser, "~> 1.4.31", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "2c6699a737ae46cb61e4ed012af931b57b699643b24dabe2400a8168414bc4f5"},
"ex_machina": {:hex, :ex_machina, "2.7.0", "b792cc3127fd0680fecdb6299235b4727a4944a09ff0fa904cc639272cd92dc7", [:mix], [{:ecto, "~> 2.2 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}, {:ecto_sql, "~> 3.0", [hex: :ecto_sql, repo: "hexpm", optional: true]}], "hexpm", "419aa7a39bde11894c87a615c4ecaa52d8f107bbdd81d810465186f783245bf8"},
"ex_syslogger": {:hex, :ex_syslogger, "1.5.2", "72b6aa2d47a236e999171f2e1ec18698740f40af0bd02c8c650bf5f1fd1bac79", [:mix], [{:poison, ">= 1.5.0", [hex: :poison, repo: "hexpm", optional: true]}, {:syslog, "~> 1.1.0", [hex: :syslog, repo: "hexpm", optional: false]}], "hexpm", "ab9fab4136dbc62651ec6f16fa4842f10cf02ab4433fa3d0976c01be99398399"},
+ "expo": {:hex, :expo, "0.4.1", "1c61d18a5df197dfda38861673d392e642649a9cef7694d2f97a587b2cfb319b", [:mix], [], "hexpm", "2ff7ba7a798c8c543c12550fa0e2cbc81b95d4974c65855d8d15ba7b37a1ce47"},
"fast_html": {:hex, :fast_html, "2.0.5", "c61760340606c1077ff1f196f17834056cb1dd3d5cb92a9f2cabf28bc6221c3c", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2.0", [hex: :nimble_pool, repo: "hexpm", optional: false]}], "hexpm", "605f4f4829443c14127694ebabb681778712ceecb4470ec32aa31012330e6506"},
"fast_sanitize": {:hex, :fast_sanitize, "0.2.3", "67b93dfb34e302bef49fec3aaab74951e0f0602fd9fa99085987af05bd91c7a5", [:mix], [{:fast_html, "~> 2.0", [hex: :fast_html, repo: "hexpm", optional: false]}, {:plug, "~> 1.8", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "e8ad286d10d0386e15d67d0ee125245ebcfbc7d7290b08712ba9013c8c5e56e2"},
"file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"},
@@ -49,7 +50,7 @@
"flake_id": {:hex, :flake_id, "0.1.0", "7716b086d2e405d09b647121a166498a0d93d1a623bead243e1f74216079ccb3", [:mix], [{:base62, "~> 1.2", [hex: :base62, repo: "hexpm", optional: false]}, {:ecto, ">= 2.0.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm", "31fc8090fde1acd267c07c36ea7365b8604055f897d3a53dd967658c691bd827"},
"floki": {:hex, :floki, "0.34.2", "5fad07ef153b3b8ec110b6b155ec3780c4b2c4906297d0b4be1a7162d04a7e02", [:mix], [], "hexpm", "26b9d50f0f01796bc6be611ca815c5e0de034d2128e39cc9702eee6b66a4d1c8"},
"gen_smtp": {:hex, :gen_smtp, "0.15.0", "9f51960c17769b26833b50df0b96123605a8024738b62db747fece14eb2fbfcc", [:rebar3], [], "hexpm", "29bd14a88030980849c7ed2447b8db6d6c9278a28b11a44cafe41b791205440f"},
- "gettext": {:git, "https://github.com/tusooa/gettext.git", "72fb2496b6c5280ed911bdc3756890e7f38a4808", [ref: "72fb2496b6c5280ed911bdc3756890e7f38a4808"]},
+ "gettext": {:hex, :gettext, "0.22.2", "6bfca374de34ecc913a28ba391ca184d88d77810a3e427afa8454a71a51341ac", [:mix], [{:expo, "~> 0.4.0", [hex: :expo, repo: "hexpm", optional: false]}], "hexpm", "8a2d389673aea82d7eae387e6a2ccc12660610080ae7beb19452cfdc1ec30f60"},
"gun": {:hex, :gun, "2.0.0", "2326bc0fd6d9cf628419708270d6fe8b02b8d002cf992e4165a77d997b1defd0", [:make, :rebar3], [{:cowlib, "2.12.0", [hex: :cowlib, repo: "hexpm", optional: false]}], "hexpm", "6613cb7c62930dc8d58263c44dda72f8556346ba88358fc929dcbc5f76d04569"},
"hackney": {:hex, :hackney, "1.18.1", "f48bf88f521f2a229fc7bae88cf4f85adc9cd9bcf23b5dc8eb6a1788c662c4f6", [:rebar3], [{:certifi, "~>2.9.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~>6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~>1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~>1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "a4ecdaff44297e9b5894ae499e9a070ea1888c84afdd1fd9b7b2bc384950128e"},
"hpax": {:hex, :hpax, "0.1.2", "09a75600d9d8bbd064cdd741f21fc06fc1f4cf3d0fcc335e5aa19be1a7235c84", [:mix], [], "hexpm", "2c87843d5a23f5f16748ebe77969880e29809580efdaccd615cd3bed628a8c13"},
diff --git a/priv/gettext/en_test/LC_MESSAGES/default.po b/priv/gettext/en_test/LC_MESSAGES/default.po
index 63db74608..037e14466 100644
--- a/priv/gettext/en_test/LC_MESSAGES/default.po
+++ b/priv/gettext/en_test/LC_MESSAGES/default.po
@@ -9,7 +9,6 @@
msgid ""
msgstr ""
"Language: en_test\n"
-"Plural-Forms: nplurals=2\n"
#, elixir-format
#: lib/pleroma/web/api_spec/render_error.ex:122
diff --git a/priv/gettext/en_test/LC_MESSAGES/errors.po b/priv/gettext/en_test/LC_MESSAGES/errors.po
index a40de7f8b..286bbb1aa 100644
--- a/priv/gettext/en_test/LC_MESSAGES/errors.po
+++ b/priv/gettext/en_test/LC_MESSAGES/errors.po
@@ -9,7 +9,6 @@
msgid ""
msgstr ""
"Language: en_test\n"
-"Plural-Forms: nplurals=2\n"
msgid "can't be blank"
msgstr ""
diff --git a/priv/gettext/en_test/LC_MESSAGES/posix_errors.po b/priv/gettext/en_test/LC_MESSAGES/posix_errors.po
index 663fc5924..6ff9dc53d 100644
--- a/priv/gettext/en_test/LC_MESSAGES/posix_errors.po
+++ b/priv/gettext/en_test/LC_MESSAGES/posix_errors.po
@@ -9,7 +9,6 @@
msgid ""
msgstr ""
"Language: en_test\n"
-"Plural-Forms: nplurals=2\n"
msgid "eperm"
msgstr ""
diff --git a/priv/gettext/en_test/LC_MESSAGES/static_pages.po b/priv/gettext/en_test/LC_MESSAGES/static_pages.po
index 1a3b7b355..daf312093 100644
--- a/priv/gettext/en_test/LC_MESSAGES/static_pages.po
+++ b/priv/gettext/en_test/LC_MESSAGES/static_pages.po
@@ -21,10 +21,6 @@ msgstr ""
#~ ##
#~ ## Use "mix gettext.extract --merge" or "mix gettext.merge"
#~ ## to merge POT files into PO files.
-#~ msgid ""
-#~ msgstr ""
-#~ "Language: en_test\n"
-#~ "Plural-Forms: nplurals=2\n"
#, elixir-format
#: lib/pleroma/web/templates/twitter_api/remote_follow/follow.html.eex:9
diff --git a/priv/gettext/ru/LC_MESSAGES/errors.po b/priv/gettext/ru/LC_MESSAGES/errors.po
index 39f83e8a6..64218da6f 100644
--- a/priv/gettext/ru/LC_MESSAGES/errors.po
+++ b/priv/gettext/ru/LC_MESSAGES/errors.po
@@ -9,7 +9,6 @@
msgid ""
msgstr ""
"Language: ru\n"
-"Plural-Forms: nplurals=3\n"
msgid "can't be blank"
msgstr "не может быть пустым"
diff --git a/priv/gettext/zh_Hans/LC_MESSAGES/static_pages.po b/priv/gettext/zh_Hans/LC_MESSAGES/static_pages.po
index cbd6feb60..809b13d47 100644
--- a/priv/gettext/zh_Hans/LC_MESSAGES/static_pages.po
+++ b/priv/gettext/zh_Hans/LC_MESSAGES/static_pages.po
@@ -24,10 +24,6 @@ msgstr ""
##
## Use "mix gettext.extract --merge" or "mix gettext.merge"
## to merge POT files into PO files.
-#~ msgid ""
-#~ msgstr ""
-#~ "Language: zh_Hans\n"
-#~ "Plural-Forms: nplurals=1\n"
#: lib/pleroma/web/templates/twitter_api/remote_follow/follow.html.eex:9
#, elixir-format
diff --git a/priv/repo/migrations/20230504173400_remove_user_ap_enabled.exs b/priv/repo/migrations/20230504173400_remove_user_ap_enabled.exs
new file mode 100644
index 000000000..0aea41324
--- /dev/null
+++ b/priv/repo/migrations/20230504173400_remove_user_ap_enabled.exs
@@ -0,0 +1,13 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2023 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Repo.Migrations.RemoveUserApEnabled do
+ use Ecto.Migration
+
+ def change do
+ alter table(:users) do
+ remove(:ap_enabled, :boolean, default: false, null: false)
+ end
+ end
+end
diff --git a/test/pleroma/ecto_type/activity_pub/object_validators/bare_uri_test.ex b/test/pleroma/ecto_type/activity_pub/object_validators/bare_uri_test.ex
new file mode 100644
index 000000000..226383c3c
--- /dev/null
+++ b/test/pleroma/ecto_type/activity_pub/object_validators/bare_uri_test.ex
@@ -0,0 +1,25 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2023 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.EctoType.ActivityPub.ObjectValidators.BareUriTest do
+ use Pleroma.DataCase, async: true
+
+ alias Pleroma.EctoType.ActivityPub.ObjectValidators.BareUri
+
+ test "diaspora://" do
+ text = "diaspora://alice@fediverse.example/post/deadbeefdeadbeefdeadbeefdeadbeef"
+ assert {:ok, text} = BareUri.cast(text)
+ end
+
+ test "nostr:" do
+ text = "nostr:note1gwdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"
+ assert {:ok, text} = BareUri.cast(text)
+ end
+
+ test "errors for non-URIs" do
+ assert :error == SafeText.cast(1)
+ assert :error == SafeText.cast("foo")
+ assert :error == SafeText.cast("foo bar")
+ end
+end
diff --git a/test/pleroma/upload/filter/only_media_test.exs b/test/pleroma/upload/filter/only_media_test.exs
new file mode 100644
index 000000000..75be070a1
--- /dev/null
+++ b/test/pleroma/upload/filter/only_media_test.exs
@@ -0,0 +1,32 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2023 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Upload.Filter.OnlyMediaTest do
+ use Pleroma.DataCase, async: true
+
+ alias Pleroma.Upload
+ alias Pleroma.Upload.Filter.OnlyMedia
+
+ test "Allows media Content-Type" do
+ ["audio/mpeg", "image/jpeg", "video/mp4"]
+ |> Enum.each(fn type ->
+ upload = %Upload{
+ content_type: type
+ }
+
+ assert {:ok, :noop} = OnlyMedia.filter(upload)
+ end)
+ end
+
+ test "Disallows non-media Content-Type" do
+ ["application/javascript", "application/pdf", "text/html"]
+ |> Enum.each(fn type ->
+ upload = %Upload{
+ content_type: type
+ }
+
+ assert {:error, _} = OnlyMedia.filter(upload)
+ end)
+ end
+end
diff --git a/test/pleroma/user_test.exs b/test/pleroma/user_test.exs
index c16312a65..7f60b959a 100644
--- a/test/pleroma/user_test.exs
+++ b/test/pleroma/user_test.exs
@@ -1844,7 +1844,6 @@ defmodule Pleroma.UserTest do
confirmation_token: "qqqq",
domain_blocks: ["lain.com"],
is_active: false,
- ap_enabled: true,
is_moderator: true,
is_admin: true,
mascot: %{"a" => "b"},
@@ -1885,7 +1884,6 @@ defmodule Pleroma.UserTest do
confirmation_token: nil,
domain_blocks: [],
is_active: false,
- ap_enabled: false,
is_moderator: false,
is_admin: false,
mascot: nil,
@@ -2473,8 +2471,7 @@ defmodule Pleroma.UserTest do
insert(:user,
local: false,
follower_address: "http://localhost:4001/users/masto_closed/followers",
- following_address: "http://localhost:4001/users/masto_closed/following",
- ap_enabled: true
+ following_address: "http://localhost:4001/users/masto_closed/following"
)
assert other_user.following_count == 0
@@ -2495,8 +2492,7 @@ defmodule Pleroma.UserTest do
insert(:user,
local: false,
follower_address: "http://localhost:4001/users/masto_closed/followers",
- following_address: "http://localhost:4001/users/masto_closed/following",
- ap_enabled: true
+ following_address: "http://localhost:4001/users/masto_closed/following"
)
assert other_user.following_count == 0
@@ -2517,8 +2513,7 @@ defmodule Pleroma.UserTest do
insert(:user,
local: false,
follower_address: "http://localhost:4001/users/masto_closed/followers",
- following_address: "http://localhost:4001/users/masto_closed/following",
- ap_enabled: true
+ following_address: "http://localhost:4001/users/masto_closed/following"
)
assert other_user.following_count == 0
diff --git a/test/pleroma/web/activity_pub/activity_pub_controller_test.exs b/test/pleroma/web/activity_pub/activity_pub_controller_test.exs
index ef91066c1..62eb9b5a3 100644
--- a/test/pleroma/web/activity_pub/activity_pub_controller_test.exs
+++ b/test/pleroma/web/activity_pub/activity_pub_controller_test.exs
@@ -575,7 +575,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
user =
insert(:user,
ap_id: "https://mastodon.example.org/users/raymoo",
- ap_enabled: true,
local: false,
last_refreshed_at: nil
)
diff --git a/test/pleroma/web/activity_pub/activity_pub_test.exs b/test/pleroma/web/activity_pub/activity_pub_test.exs
index a6f8b6152..54fc6ef0a 100644
--- a/test/pleroma/web/activity_pub/activity_pub_test.exs
+++ b/test/pleroma/web/activity_pub/activity_pub_test.exs
@@ -174,7 +174,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
{:ok, user} = ActivityPub.make_user_from_ap_id(user_id)
assert user.ap_id == user_id
assert user.nickname == "admin@mastodon.example.org"
- assert user.ap_enabled
assert user.follower_address == "http://mastodon.example.org/users/admin/followers"
end
diff --git a/test/pleroma/web/activity_pub/publisher_test.exs b/test/pleroma/web/activity_pub/publisher_test.exs
index e2db3d575..c5137cbb7 100644
--- a/test/pleroma/web/activity_pub/publisher_test.exs
+++ b/test/pleroma/web/activity_pub/publisher_test.exs
@@ -276,8 +276,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
follower =
insert(:user, %{
local: false,
- inbox: "https://domain.com/users/nick1/inbox",
- ap_enabled: true
+ inbox: "https://domain.com/users/nick1/inbox"
})
actor = insert(:user, follower_address: follower.ap_id)
@@ -313,8 +312,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
follower =
insert(:user, %{
local: false,
- inbox: "https://domain.com/users/nick1/inbox",
- ap_enabled: true
+ inbox: "https://domain.com/users/nick1/inbox"
})
actor = insert(:user, follower_address: follower.ap_id)
@@ -348,8 +346,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
follower =
insert(:user, %{
local: false,
- inbox: "https://domain.com/users/nick1/inbox",
- ap_enabled: true
+ inbox: "https://domain.com/users/nick1/inbox"
})
actor = insert(:user, follower_address: follower.ap_id)
@@ -382,15 +379,13 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
fetcher =
insert(:user,
local: false,
- inbox: "https://domain.com/users/nick1/inbox",
- ap_enabled: true
+ inbox: "https://domain.com/users/nick1/inbox"
)
another_fetcher =
insert(:user,
local: false,
- inbox: "https://domain2.com/users/nick1/inbox",
- ap_enabled: true
+ inbox: "https://domain2.com/users/nick1/inbox"
)
actor = insert(:user)
diff --git a/test/pleroma/web/activity_pub/transmogrifier_test.exs b/test/pleroma/web/activity_pub/transmogrifier_test.exs
index f76606479..3e0c8dc65 100644
--- a/test/pleroma/web/activity_pub/transmogrifier_test.exs
+++ b/test/pleroma/web/activity_pub/transmogrifier_test.exs
@@ -8,7 +8,6 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
alias Pleroma.Activity
alias Pleroma.Object
- alias Pleroma.Tests.ObanHelpers
alias Pleroma.User
alias Pleroma.Web.ActivityPub.Transmogrifier
alias Pleroma.Web.ActivityPub.Utils
@@ -353,69 +352,6 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
end
end
- describe "user upgrade" do
- test "it upgrades a user to activitypub" do
- user =
- insert(:user, %{
- nickname: "rye@niu.moe",
- local: false,
- ap_id: "https://niu.moe/users/rye",
- follower_address: User.ap_followers(%User{nickname: "rye@niu.moe"})
- })
-
- user_two = insert(:user)
- Pleroma.FollowingRelationship.follow(user_two, user, :follow_accept)
-
- {:ok, activity} = CommonAPI.post(user, %{status: "test"})
- {:ok, unrelated_activity} = CommonAPI.post(user_two, %{status: "test"})
- assert "http://localhost:4001/users/rye@niu.moe/followers" in activity.recipients
-
- user = User.get_cached_by_id(user.id)
- assert user.note_count == 1
-
- {:ok, user} = Transmogrifier.upgrade_user_from_ap_id("https://niu.moe/users/rye")
- ObanHelpers.perform_all()
-
- assert user.ap_enabled
- assert user.note_count == 1
- assert user.follower_address == "https://niu.moe/users/rye/followers"
- assert user.following_address == "https://niu.moe/users/rye/following"
-
- user = User.get_cached_by_id(user.id)
- assert user.note_count == 1
-
- activity = Activity.get_by_id(activity.id)
- assert user.follower_address in activity.recipients
-
- assert %{
- "url" => [
- %{
- "href" =>
- "https://cdn.niu.moe/accounts/avatars/000/033/323/original/fd7f8ae0b3ffedc9.jpeg"
- }
- ]
- } = user.avatar
-
- assert %{
- "url" => [
- %{
- "href" =>
- "https://cdn.niu.moe/accounts/headers/000/033/323/original/850b3448fa5fd477.png"
- }
- ]
- } = user.banner
-
- refute "..." in activity.recipients
-
- unrelated_activity = Activity.get_by_id(unrelated_activity.id)
- refute user.follower_address in unrelated_activity.recipients
-
- user_two = User.get_cached_by_id(user_two.id)
- assert User.following?(user_two, user)
- refute "..." in User.following(user_two)
- end
- end
-
describe "actor rewriting" do
test "it fixes the actor URL property to be a proper URI" do
data = %{
diff --git a/test/pleroma/web/common_api_test.exs b/test/pleroma/web/common_api_test.exs
index 968d826a2..3112d831b 100644
--- a/test/pleroma/web/common_api_test.exs
+++ b/test/pleroma/web/common_api_test.exs
@@ -1339,7 +1339,7 @@ defmodule Pleroma.Web.CommonAPITest do
test "cancels a pending follow for a remote user" do
follower = insert(:user)
- followed = insert(:user, is_locked: true, local: false, ap_enabled: true)
+ followed = insert(:user, is_locked: true, local: false)
assert {:ok, follower, followed, %{id: activity_id, data: %{"state" => "pending"}}} =
CommonAPI.follow(follower, followed)
diff --git a/test/pleroma/web/federator_test.exs b/test/pleroma/web/federator_test.exs
index 1ffe6aae1..6826e6c2f 100644
--- a/test/pleroma/web/federator_test.exs
+++ b/test/pleroma/web/federator_test.exs
@@ -78,16 +78,14 @@ defmodule Pleroma.Web.FederatorTest do
local: false,
nickname: "nick1@domain.com",
ap_id: "https://domain.com/users/nick1",
- inbox: inbox1,
- ap_enabled: true
+ inbox: inbox1
})
insert(:user, %{
local: false,
nickname: "nick2@domain2.com",
ap_id: "https://domain2.com/users/nick2",
- inbox: inbox2,
- ap_enabled: true
+ inbox: inbox2
})
dt = NaiveDateTime.utc_now()
diff --git a/test/pleroma/web/media_proxy/media_proxy_controller_test.exs b/test/pleroma/web/media_proxy/media_proxy_controller_test.exs
index 5246bf0c4..9ce092fd8 100644
--- a/test/pleroma/web/media_proxy/media_proxy_controller_test.exs
+++ b/test/pleroma/web/media_proxy/media_proxy_controller_test.exs
@@ -6,7 +6,9 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
use Pleroma.Web.ConnCase
import Mock
+ import Mox
+ alias Pleroma.ReverseProxy.ClientMock
alias Pleroma.Web.MediaProxy
alias Plug.Conn
@@ -74,6 +76,20 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
assert %Conn{status: 404, resp_body: "Not Found"} = get(conn, url)
end
end
+
+ test "it applies sandbox CSP to MediaProxy requests", %{conn: conn} do
+ media_url = "https://lain.com/image.png"
+ media_proxy_url = MediaProxy.encode_url(media_url)
+
+ ClientMock
+ |> expect(:request, fn :get, ^media_url, _, _, _ ->
+ {:ok, 200, [{"content-type", "image/png"}]}
+ end)
+
+ %Conn{resp_headers: headers} = get(conn, media_proxy_url)
+
+ assert {"content-security-policy", "sandbox;"} in headers
+ end
end
describe "Media Preview Proxy" do
diff --git a/test/pleroma/web/metadata/providers/twitter_card_test.exs b/test/pleroma/web/metadata/providers/twitter_card_test.exs
index be4cfbe7b..f8d01c5c8 100644
--- a/test/pleroma/web/metadata/providers/twitter_card_test.exs
+++ b/test/pleroma/web/metadata/providers/twitter_card_test.exs
@@ -182,7 +182,8 @@ defmodule Pleroma.Web.Metadata.Providers.TwitterCardTest do
{:meta, [name: "twitter:title", content: Utils.user_name_string(user)], []},
{:meta, [name: "twitter:description", content: "pleroma in a nutshell"], []},
{:meta, [name: "twitter:card", content: "summary_large_image"], []},
- {:meta, [name: "twitter:player", content: "https://pleroma.gov/tenshi.png"], []},
+ {:meta, [name: "twitter:image", content: "https://pleroma.gov/tenshi.png"], []},
+ {:meta, [name: "twitter:image:alt", content: ""], []},
{:meta, [name: "twitter:player:width", content: "1280"], []},
{:meta, [name: "twitter:player:height", content: "1024"], []},
{:meta, [name: "twitter:card", content: "player"], []},
diff --git a/test/pleroma/web/plugs/uploaded_media_plug_test.exs b/test/pleroma/web/plugs/uploaded_media_plug_test.exs
index 8323ff6ab..dbf8ca5ec 100644
--- a/test/pleroma/web/plugs/uploaded_media_plug_test.exs
+++ b/test/pleroma/web/plugs/uploaded_media_plug_test.exs
@@ -40,4 +40,30 @@ defmodule Pleroma.Web.Plugs.UploadedMediaPlugTest do
&(&1 == {"content-disposition", ~s[inline; filename="\\"cofe\\".gif"]})
)
end
+
+ test "denies access to media if wrong Host", %{
+ attachment_url: attachment_url
+ } do
+ conn = get(build_conn(), attachment_url)
+
+ assert conn.status == 200
+
+ new_media_base = "http://media.localhost:8080"
+
+ %{scheme: new_media_scheme, host: new_media_host, port: new_media_port} =
+ URI.parse(new_media_base)
+
+ clear_config([Pleroma.Upload, :base_url], new_media_base)
+
+ conn = get(build_conn(), attachment_url)
+
+ expected_url =
+ URI.parse(attachment_url)
+ |> Map.put(:host, new_media_host)
+ |> Map.put(:port, new_media_port)
+ |> Map.put(:scheme, new_media_scheme)
+ |> URI.to_string()
+
+ assert redirected_to(conn, 302) == expected_url
+ end
end
diff --git a/test/pleroma/web/rich_media/parser_test.exs b/test/pleroma/web/rich_media/parser_test.exs
index ffdc4e5d7..9064138a6 100644
--- a/test/pleroma/web/rich_media/parser_test.exs
+++ b/test/pleroma/web/rich_media/parser_test.exs
@@ -129,7 +129,7 @@ defmodule Pleroma.Web.RichMedia.ParserTest do
}}
end
- test "parses OEmbed" do
+ test "parses OEmbed and filters HTML tags" do
assert Parser.parse("http://example.com/oembed") ==
{:ok,
%{
@@ -139,7 +139,7 @@ defmodule Pleroma.Web.RichMedia.ParserTest do
"flickr_type" => "photo",
"height" => "768",
"html" =>
- "<a data-flickr-embed=\"true\" href=\"https://www.flickr.com/photos/bees/2362225867/\" title=\"Bacon Lollys by \u202E\u202D\u202Cbees\u202C, on Flickr\"><img src=\"https://farm4.staticflickr.com/3040/2362225867_4a87ab8baf_b.jpg\" width=\"1024\" height=\"768\" alt=\"Bacon Lollys\"></a><script async src=\"https://embedr.flickr.com/assets/client-code.js\" charset=\"utf-8\"></script>",
+ "<a href=\"https://www.flickr.com/photos/bees/2362225867/\" title=\"Bacon Lollys by \u202E\u202D\u202Cbees\u202C, on Flickr\"><img src=\"https://farm4.staticflickr.com/3040/2362225867_4a87ab8baf_b.jpg\" width=\"1024\" height=\"768\" alt=\"Bacon Lollys\"/></a>",
"license" => "All Rights Reserved",
"license_id" => 0,
"provider_name" => "Flickr",
diff --git a/test/pleroma/web/streamer_test.exs b/test/pleroma/web/streamer_test.exs
index 8b0c84164..7ab0e379b 100644
--- a/test/pleroma/web/streamer_test.exs
+++ b/test/pleroma/web/streamer_test.exs
@@ -29,6 +29,26 @@ defmodule Pleroma.Web.StreamerTest do
assert {:ok, "public:local:media"} = Streamer.get_topic("public:local:media", nil, nil)
end
+ test "rejects local public streams if restricted_unauthenticated is on" do
+ clear_config([:restrict_unauthenticated, :timelines, :local], true)
+
+ assert {:error, :unauthorized} = Streamer.get_topic("public:local", nil, nil)
+ assert {:error, :unauthorized} = Streamer.get_topic("public:local:media", nil, nil)
+ end
+
+ test "rejects remote public streams if restricted_unauthenticated is on" do
+ clear_config([:restrict_unauthenticated, :timelines, :federated], true)
+
+ assert {:error, :unauthorized} = Streamer.get_topic("public", nil, nil)
+ assert {:error, :unauthorized} = Streamer.get_topic("public:media", nil, nil)
+
+ assert {:error, :unauthorized} =
+ Streamer.get_topic("public:remote", nil, nil, %{"instance" => "lain.com"})
+
+ assert {:error, :unauthorized} =
+ Streamer.get_topic("public:remote:media", nil, nil, %{"instance" => "lain.com"})
+ end
+
test "allows instance streams" do
assert {:ok, "public:remote:lain.com"} =
Streamer.get_topic("public:remote", nil, nil, %{"instance" => "lain.com"})
@@ -69,6 +89,63 @@ defmodule Pleroma.Web.StreamerTest do
end
end
+ test "allows local public streams if restricted_unauthenticated is on", %{
+ user: user,
+ token: oauth_token
+ } do
+ clear_config([:restrict_unauthenticated, :timelines, :local], true)
+
+ %{token: read_notifications_token} = oauth_access(["read:notifications"], user: user)
+ %{token: badly_scoped_token} = oauth_access(["irrelevant:scope"], user: user)
+
+ assert {:ok, "public:local"} = Streamer.get_topic("public:local", user, oauth_token)
+
+ assert {:ok, "public:local:media"} =
+ Streamer.get_topic("public:local:media", user, oauth_token)
+
+ for token <- [read_notifications_token, badly_scoped_token] do
+ assert {:error, :unauthorized} = Streamer.get_topic("public:local", user, token)
+
+ assert {:error, :unauthorized} = Streamer.get_topic("public:local:media", user, token)
+ end
+ end
+
+ test "allows remote public streams if restricted_unauthenticated is on", %{
+ user: user,
+ token: oauth_token
+ } do
+ clear_config([:restrict_unauthenticated, :timelines, :federated], true)
+
+ %{token: read_notifications_token} = oauth_access(["read:notifications"], user: user)
+ %{token: badly_scoped_token} = oauth_access(["irrelevant:scope"], user: user)
+
+ assert {:ok, "public"} = Streamer.get_topic("public", user, oauth_token)
+ assert {:ok, "public:media"} = Streamer.get_topic("public:media", user, oauth_token)
+
+ assert {:ok, "public:remote:lain.com"} =
+ Streamer.get_topic("public:remote", user, oauth_token, %{"instance" => "lain.com"})
+
+ assert {:ok, "public:remote:media:lain.com"} =
+ Streamer.get_topic("public:remote:media", user, oauth_token, %{
+ "instance" => "lain.com"
+ })
+
+ for token <- [read_notifications_token, badly_scoped_token] do
+ assert {:error, :unauthorized} = Streamer.get_topic("public", user, token)
+ assert {:error, :unauthorized} = Streamer.get_topic("public:media", user, token)
+
+ assert {:error, :unauthorized} =
+ Streamer.get_topic("public:remote", user, token, %{
+ "instance" => "lain.com"
+ })
+
+ assert {:error, :unauthorized} =
+ Streamer.get_topic("public:remote:media", user, token, %{
+ "instance" => "lain.com"
+ })
+ end
+ end
+
test "allows user streams (with proper OAuth token scopes)", %{
user: user,
token: read_oauth_token
diff --git a/test/support/factory.ex b/test/support/factory.ex
index 09f02458c..d94544717 100644
--- a/test/support/factory.ex
+++ b/test/support/factory.ex
@@ -50,7 +50,6 @@ defmodule Pleroma.Factory do
last_refreshed_at: NaiveDateTime.utc_now(),
notification_settings: %Pleroma.User.NotificationSetting{},
multi_factor_authentication_settings: %Pleroma.MFA.Settings{},
- ap_enabled: true,
keys: pem
}