Compare commits

...

18 Commits

Author SHA1 Message Date
Haelwenn
d8e326467c Merge branch 'fix/2.4.5-release-date' into 'stable'
Fix changelog date

See merge request pleroma/pleroma!3796
2022-11-28 04:35:51 +00:00
Sean King
75c9f7770f
Fix changelog date 2022-11-27 20:17:48 -07:00
Haelwenn
76bdb01c18 Merge branch 'release/2.4.5' into 'stable'
Release 2.4.5

See merge request pleroma/pleroma!3793
2022-11-27 21:24:19 +00:00
Haelwenn (lanodan) Monnier
2614f431b9 Release 2.4.5 2022-11-27 13:17:21 +01:00
Hélène
542bb17258 ArticleNotePageValidator: fix replies fixing
Some software, like GoToSocial, expose replies as ActivityPub
Collections, but do not expose any item array directly in the object,
causing validation to fail via the ObjectID validator. Now, Pleroma will
drop that field in this situation too.
2022-11-27 04:54:19 +01:00
FloatingGhost
747311f623 fix resolution of GTS user keys 2022-11-27 04:54:18 +01:00
Tusooa Zhu
11d5ad24c5 Make local-only posts stream in local timeline 2022-11-27 04:39:32 +01:00
Tusooa Zhu
e46c3a0595 Do not stream out Create of ChatMessage 2022-11-27 04:39:32 +01:00
Sean King
9b68778887 Fix fedi-fe build URL 2022-11-27 04:34:33 +01:00
Haelwenn (lanodan) Monnier
f2221d539c script_test: Fix %ErlangError for Elixir 1.14 2022-11-27 04:25:48 +01:00
Haelwenn (lanodan) Monnier
915c7319c6 mix: Switch prometheus_ex to fix/elixir-1.14 branch 2022-11-27 04:25:48 +01:00
Haelwenn (lanodan) Monnier
f12ddcd697 timeline_controller_test: Fix test name for elixir 1.14 2022-11-27 04:25:48 +01:00
Tusooa Zhu
09ab51eebb Make mutes and blocks behave the same as other lists 2022-11-27 04:21:58 +01:00
Haelwenn (lanodan) Monnier
7ec3469bea Transmogrifier: Use validating regex for "mediaType" 2022-11-27 04:21:31 +01:00
Haelwenn (lanodan) Monnier
8640d217b1 AttachmentValidator: Use custom ecto type and regex for "mediaType" 2022-11-27 04:21:31 +01:00
Haelwenn (lanodan) Monnier
da71092003 EctoType: Add MIME validator 2022-11-27 04:21:31 +01:00
Ilja
4504c81080 Delete report notifs when demoting from superuser
When someone isn't a superuser any more, they shouldn't see the reporsts any more either.
Here we delete the report notifications from a user when that user gets updated from being a superuser to a non-superuser.
2022-11-27 04:20:11 +01:00
Haelwenn (lanodan) Monnier
508b438b53 scrubbers: Scrub img class attribute
Closes: https://git.pleroma.social/pleroma/pleroma/-/merge_requests/3790
2022-11-27 04:04:17 +01:00
26 changed files with 371 additions and 48 deletions

View File

@ -14,6 +14,20 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Removed
## 2.4.5 - 2022-11-27
## Fixed
- Image `class` attributes not being scrubbed, allowing to exploit frontend special classes [!3792](https://git.pleroma.social/pleroma/pleroma/-/merge_requests/3792)
- Delete report notifs when demoting from superuser [!3642](https://git.pleroma.social/pleroma/pleroma/-/merge_requests/3642)
- Validate `mediaType` only by it's format rather than using a list [!3597](https://git.pleroma.social/pleroma/pleroma/-/merge_requests/3597)
- Pagination: Make mutes and blocks lists behave the same as other lists [!3693](https://git.pleroma.social/pleroma/pleroma/-/merge_requests/3693)
- Compatibility with Elixir 1.14 [!3740](https://git.pleroma.social/pleroma/pleroma/-/merge_requests/3740)
- Frontend installer: FediFE build URL [!3736](https://git.pleroma.social/pleroma/pleroma/-/merge_requests/3736)
- Streaming: Don't stream ChatMessage into the home timeline [!3738](https://git.pleroma.social/pleroma/pleroma/-/merge_requests/3738)
- Streaming: Stream local-only posts in the local timeline [!3738](https://git.pleroma.social/pleroma/pleroma/-/merge_requests/3738)
- Signatures: Fix `keyId` lookup for GoToSocial [!3725](https://git.pleroma.social/pleroma/pleroma/-/merge_requests/3725)
- Validator: Fix `replies` handling for GoToSocial [!3725](https://git.pleroma.social/pleroma/pleroma/-/merge_requests/3725)
## 2.4.4 - 2022-08-19
### Security

View File

@ -734,7 +734,7 @@ config :pleroma, :frontends,
"name" => "fedi-fe",
"git" => "https://git.pleroma.social/pleroma/fedi-fe",
"build_url" =>
"https://git.pleroma.social/pleroma/fedi-fe/-/jobs/artifacts/${ref}/download?job=build",
"https://git.pleroma.social/pleroma/fedi-fe/-/jobs/artifacts/${ref}/download?job=build_release",
"ref" => "master",
"custom-http-headers" => [
{"service-worker-allowed", "/"}

View File

@ -13,6 +13,14 @@ defmodule Pleroma.Activity.Ir.Topics do
|> List.flatten()
end
defp generate_topics(%{data: %{"type" => "ChatMessage"}}, %{data: %{"type" => "Delete"}}) do
["user", "user:pleroma_chat"]
end
defp generate_topics(%{data: %{"type" => "ChatMessage"}}, %{data: %{"type" => "Create"}}) do
[]
end
defp generate_topics(%{data: %{"type" => "Answer"}}, _) do
[]
end
@ -31,6 +39,10 @@ defmodule Pleroma.Activity.Ir.Topics do
end
|> item_creation_tags(object, activity)
"local" ->
["public:local"]
|> item_creation_tags(object, activity)
"direct" ->
["direct"]
@ -63,7 +75,18 @@ defmodule Pleroma.Activity.Ir.Topics do
defp attachment_topics(%{data: %{"attachment" => []}}, _act), do: []
defp attachment_topics(_object, %{local: true}), do: ["public:media", "public:local:media"]
defp attachment_topics(_object, %{local: true} = activity) do
case Visibility.get_visibility(activity) do
"public" ->
["public:media", "public:local:media"]
"local" ->
["public:local:media"]
_ ->
[]
end
end
defp attachment_topics(_object, %{actor: actor}) when is_binary(actor),
do: ["public:media", "public:remote:media:" <> URI.parse(actor).host]

View File

@ -27,4 +27,10 @@ defmodule Pleroma.Constants do
do:
~w(index.html robots.txt static static-fe finmoji emoji packs sounds images instance sw.js sw-pleroma.js favicon.png schemas doc embed.js embed.css)
)
# basic regex, just there to weed out potential mistakes
# https://datatracker.ietf.org/doc/html/rfc2045#section-5.1
const(mime_regex,
do: ~r/^[^[:cntrl:] ()<>@,;:\\"\/\[\]?=]+\/[^[:cntrl:] ()<>@,;:\\"\/\[\]?=]+(; .*)?$/
)
end

View File

@ -0,0 +1,25 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.EctoType.ActivityPub.ObjectValidators.MIME do
use Ecto.Type
require Pleroma.Constants
def type, do: :string
def cast(mime) when is_binary(mime) do
if mime =~ Pleroma.Constants.mime_regex() do
{:ok, mime}
else
{:ok, "application/octet-stream"}
end
end
def cast(_), do: :error
def dump(data), do: {:ok, data}
def load(data), do: {:ok, data}
end

View File

@ -328,6 +328,14 @@ defmodule Pleroma.Notification do
|> Repo.delete_all()
end
def destroy_multiple_from_types(%{id: user_id}, types) do
from(n in Notification,
where: n.user_id == ^user_id,
where: n.type in ^types
)
|> Repo.delete_all()
end
def dismiss(%Pleroma.Activity{} = activity) do
Notification
|> where([n], n.activity_id == ^activity.id)

View File

@ -10,17 +10,14 @@ defmodule Pleroma.Signature do
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub
@known_suffixes ["/publickey", "/main-key"]
def key_id_to_actor_id(key_id) do
uri =
URI.parse(key_id)
key_id
|> URI.parse()
|> Map.put(:fragment, nil)
uri =
if not is_nil(uri.path) and String.ends_with?(uri.path, "/publickey") do
Map.put(uri, :path, String.replace(uri.path, "/publickey", ""))
else
uri
end
|> remove_suffix(@known_suffixes)
maybe_ap_id = URI.to_string(uri)
@ -36,6 +33,16 @@ defmodule Pleroma.Signature do
end
end
defp remove_suffix(uri, [test | rest]) do
if not is_nil(uri.path) and String.ends_with?(uri.path, test) do
Map.put(uri, :path, String.replace(uri.path, test, ""))
else
remove_suffix(uri, rest)
end
end
defp remove_suffix(uri, []), do: uri
def fetch_public_key(conn) do
with %{"keyId" => kid} <- HTTPSignatures.signature_for_conn(conn),
{:ok, actor_id} <- key_id_to_actor_id(kid),

View File

@ -1087,10 +1087,24 @@ defmodule Pleroma.User do
|> update_and_set_cache()
end
def update_and_set_cache(changeset) do
def update_and_set_cache(%{data: %Pleroma.User{} = user} = changeset) do
was_superuser_before_update = User.superuser?(user)
with {:ok, user} <- Repo.update(changeset, stale_error_field: :id) do
set_cache(user)
end
|> maybe_remove_report_notifications(was_superuser_before_update)
end
defp maybe_remove_report_notifications({:ok, %Pleroma.User{} = user} = result, true) do
if not User.superuser?(user),
do: user |> Notification.destroy_multiple_from_types(["pleroma:report"])
result
end
defp maybe_remove_report_notifications(result, _) do
result
end
def get_user_friends_ap_ids(user) do

View File

@ -86,7 +86,10 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNotePageValidator do
defp fix_replies(%{"replies" => %{"items" => replies}} = data) when is_list(replies),
do: Map.put(data, "replies", replies)
defp fix_replies(%{"replies" => replies} = data) when is_bitstring(replies),
# TODO: Pleroma does not have any support for Collections at the moment.
# If the `replies` field is not something the ObjectID validator can handle,
# the activity/object would be rejected, which is bad behavior.
defp fix_replies(%{"replies" => replies} = data) when not is_list(replies),
do: Map.drop(data, ["replies"])
defp fix_replies(data), do: data

View File

@ -12,14 +12,14 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidator do
@primary_key false
embedded_schema do
field(:type, :string)
field(:mediaType, :string, default: "application/octet-stream")
field(:mediaType, ObjectValidators.MIME, default: "application/octet-stream")
field(:name, :string)
field(:blurhash, :string)
embeds_many :url, UrlObjectValidator, primary_key: false do
field(:type, :string)
field(:href, ObjectValidators.Uri)
field(:mediaType, :string, default: "application/octet-stream")
field(:mediaType, ObjectValidators.MIME, default: "application/octet-stream")
field(:width, :integer)
field(:height, :integer)
end
@ -59,13 +59,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidator do
end
def fix_media_type(data) do
data = Map.put_new(data, "mediaType", data["mimeType"])
if is_bitstring(data["mediaType"]) && MIME.extensions(data["mediaType"]) != [] do
data
else
Map.put(data, "mediaType", "application/octet-stream")
end
Map.put_new(data, "mediaType", data["mimeType"])
end
defp handle_href(href, mediaType) do

View File

@ -203,13 +203,13 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
media_type =
cond do
is_map(url) && MIME.extensions(url["mediaType"]) != [] ->
is_map(url) && url =~ Pleroma.Constants.mime_regex() ->
url["mediaType"]
is_bitstring(data["mediaType"]) && MIME.extensions(data["mediaType"]) != [] ->
is_bitstring(data["mediaType"]) && data["mediaType"] =~ Pleroma.Constants.mime_regex() ->
data["mediaType"]
is_bitstring(data["mimeType"]) && MIME.extensions(data["mimeType"]) != [] ->
is_bitstring(data["mimeType"]) && data["mimeType"] =~ Pleroma.Constants.mime_regex() ->
data["mimeType"]
true ->

View File

@ -453,7 +453,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
users =
user
|> User.muted_users_relation(_restrict_deactivated = true)
|> Pleroma.Pagination.fetch_paginated(Map.put(params, :skip_order, true))
|> Pleroma.Pagination.fetch_paginated(params)
conn
|> add_link_headers(users)
@ -470,7 +470,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
users =
user
|> User.blocked_users_relation(_restrict_deactivated = true)
|> Pleroma.Pagination.fetch_paginated(Map.put(params, :skip_order, true))
|> Pleroma.Pagination.fetch_paginated(params)
conn
|> add_link_headers(users)

View File

@ -4,7 +4,7 @@ defmodule Pleroma.Mixfile do
def project do
[
app: :pleroma,
version: version("2.4.4"),
version: version("2.4.5"),
elixir: "~> 1.9",
elixirc_paths: elixirc_paths(Mix.env()),
compilers: [:phoenix, :gettext] ++ Mix.compilers(),
@ -163,8 +163,8 @@ defmodule Pleroma.Mixfile do
{:poolboy, "~> 1.5"},
{:prometheus, "~> 4.6"},
{:prometheus_ex,
git: "https://git.pleroma.social/pleroma/elixir-libraries/prometheus.ex.git",
ref: "a4e9beb3c1c479d14b352fd9d6dd7b1f6d7deee5",
git: "https://github.com/lanodan/prometheus.ex.git",
branch: "fix/elixir-1.14",
override: true},
{:prometheus_plugs, "~> 1.1"},
{:prometheus_phoenix, "~> 1.3"},

View File

@ -104,7 +104,7 @@
"pot": {:hex, :pot, "1.0.1", "81b511b1fa7c3123171c265cb7065a1528cebd7277b0cbc94257c50a8b2e4c17", [:rebar3], [], "hexpm", "ed87f5976531d91528452faa1138a5328db7f9f20d8feaae15f5051f79bcfb6d"},
"prometheus": {:hex, :prometheus, "4.8.0", "1ce1e1002b173c336d61f186b56263346536e76814edd9a142e12aeb2d6c1ad2", [:mix, :rebar3], [], "hexpm", "0fc2e17103073edb3758a46a5d44b006191bf25b73cbaa2b779109de396afcb5"},
"prometheus_ecto": {:hex, :prometheus_ecto, "1.4.3", "3dd4da1812b8e0dbee81ea58bb3b62ed7588f2eae0c9e97e434c46807ff82311", [:mix], [{:ecto, "~> 2.0 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:prometheus_ex, "~> 1.1 or ~> 2.0 or ~> 3.0", [hex: :prometheus_ex, repo: "hexpm", optional: false]}], "hexpm", "8d66289f77f913b37eda81fd287340c17e61a447549deb28efc254532b2bed82"},
"prometheus_ex": {:git, "https://git.pleroma.social/pleroma/elixir-libraries/prometheus.ex.git", "a4e9beb3c1c479d14b352fd9d6dd7b1f6d7deee5", [ref: "a4e9beb3c1c479d14b352fd9d6dd7b1f6d7deee5"]},
"prometheus_ex": {:git, "https://github.com/lanodan/prometheus.ex.git", "31f7fbe4b71b79ba27efc2a5085746c4011ceb8f", [branch: "fix/elixir-1.14"]},
"prometheus_phoenix": {:hex, :prometheus_phoenix, "1.3.0", "c4b527e0b3a9ef1af26bdcfbfad3998f37795b9185d475ca610fe4388fdd3bb5", [:mix], [{:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}, {:prometheus_ex, "~> 1.3 or ~> 2.0 or ~> 3.0", [hex: :prometheus_ex, repo: "hexpm", optional: false]}], "hexpm", "c4d1404ac4e9d3d963da601db2a7d8ea31194f0017057fabf0cfb9bf5a6c8c75"},
"prometheus_phx": {:git, "https://git.pleroma.social/pleroma/elixir-libraries/prometheus-phx.git", "9cd8f248c9381ffedc799905050abce194a97514", [branch: "no-logging"]},
"prometheus_plugs": {:hex, :prometheus_plugs, "1.1.5", "25933d48f8af3a5941dd7b621c889749894d8a1082a6ff7c67cc99dec26377c5", [:mix], [{:accept, "~> 0.1", [hex: :accept, repo: "hexpm", optional: false]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}, {:prometheus_ex, "~> 1.1 or ~> 2.0 or ~> 3.0", [hex: :prometheus_ex, repo: "hexpm", optional: false]}, {:prometheus_process_collector, "~> 1.1", [hex: :prometheus_process_collector, repo: "hexpm", optional: true]}], "hexpm", "0273a6483ccb936d79ca19b0ab629aef0dba958697c94782bb728b920dfc6a79"},

View File

@ -64,13 +64,14 @@ defmodule Pleroma.HTML.Scrubber.Default do
@allow_inline_images Pleroma.Config.get([:markup, :allow_inline_images])
if @allow_inline_images do
Meta.allow_tag_with_this_attribute_values(:img, "class", ["emoji"])
# restrict img tags to http/https only, because of MediaProxy.
Meta.allow_tag_with_uri_attributes(:img, ["src"], ["http", "https"])
Meta.allow_tag_with_these_attributes(:img, [
"width",
"height",
"class",
"title",
"alt"
])

View File

@ -41,13 +41,14 @@ defmodule Pleroma.HTML.Scrubber.TwitterText do
# allow inline images for custom emoji
if Pleroma.Config.get([:markup, :allow_inline_images]) do
Meta.allow_tag_with_this_attribute_values(:img, "class", ["emoji"])
# restrict img tags to http/https only, because of MediaProxy.
Meta.allow_tag_with_uri_attributes(:img, ["src"], ["http", "https"])
Meta.allow_tag_with_these_attributes(:img, [
"width",
"height",
"class",
"title",
"alt"
])

View File

@ -13,6 +13,29 @@ defmodule Pleroma.Activity.Ir.TopicsTest do
import Mock
describe "chat message" do
test "Create produces no topics" do
activity = %Activity{
object: %Object{data: %{"type" => "ChatMessage"}},
data: %{"type" => "Create"}
}
assert [] == Topics.get_activity_topics(activity)
end
test "Delete produces user and user:pleroma_chat" do
activity = %Activity{
object: %Object{data: %{"type" => "ChatMessage"}},
data: %{"type" => "Delete"}
}
topics = Topics.get_activity_topics(activity)
assert [_, _] = topics
assert "user" in topics
assert "user:pleroma_chat" in topics
end
end
describe "poll answer" do
test "produce no topics" do
activity = %Activity{object: %Object{data: %{"type" => "Answer"}}}
@ -114,6 +137,36 @@ defmodule Pleroma.Activity.Ir.TopicsTest do
end
end
describe "local-public visibility create events" do
setup do
activity = %Activity{
object: %Object{data: %{"attachment" => []}},
data: %{"type" => "Create", "to" => [Pleroma.Web.ActivityPub.Utils.as_local_public()]}
}
{:ok, activity: activity}
end
test "doesn't produce public topics", %{activity: activity} do
topics = Topics.get_activity_topics(activity)
refute Enum.member?(topics, "public")
end
test "produces public:local topics", %{activity: activity} do
topics = Topics.get_activity_topics(activity)
assert Enum.member?(topics, "public:local")
end
test "with no attachments doesn't produce public:media topics", %{activity: activity} do
topics = Topics.get_activity_topics(activity)
refute Enum.member?(topics, "public:media")
refute Enum.member?(topics, "public:local:media")
end
end
describe "public visibility create events with attachments" do
setup do
activity = %Activity{
@ -152,6 +205,29 @@ defmodule Pleroma.Activity.Ir.TopicsTest do
end
end
describe "local-public visibility create events with attachments" do
setup do
activity = %Activity{
object: %Object{data: %{"attachment" => ["foo"]}},
data: %{"type" => "Create", "to" => [Pleroma.Web.ActivityPub.Utils.as_local_public()]}
}
{:ok, activity: activity}
end
test "do not produce public:media topics", %{activity: activity} do
topics = Topics.get_activity_topics(activity)
refute Enum.member?(topics, "public:media")
end
test "produces public:local:media topics", %{activity: activity} do
topics = Topics.get_activity_topics(activity)
assert Enum.member?(topics, "public:local:media")
end
end
describe "non-public visibility" do
test "produces direct topic" do
activity = %Activity{object: %Object{data: %{"type" => "Note"}}, data: %{"to" => []}}

View File

@ -17,6 +17,7 @@ defmodule Pleroma.HTMLTest do
this is a link with allowed "rel" attribute: <a href="http://example.com/" rel="tag">example.com</a>
this is a link with not allowed "rel" attribute: <a href="http://example.com/" rel="tag noallowed">example.com</a>
this is an image: <img src="http://example.com/image.jpg"><br />
this is an inline emoji: <img class="emoji" src="http://example.com/image.jpg"><br />
<script>alert('hacked')</script>
"""
@ -24,6 +25,10 @@ defmodule Pleroma.HTMLTest do
<img src="http://example.com/image.jpg" onerror="alert('hacked')">
"""
@html_stillimage_sample """
<img class="still-image" src="http://example.com/image.jpg">
"""
@html_span_class_sample """
<span class="animate-spin">hi</span>
"""
@ -45,6 +50,7 @@ defmodule Pleroma.HTMLTest do
this is a link with allowed &quot;rel&quot; attribute: example.com
this is a link with not allowed &quot;rel&quot; attribute: example.com
this is an image:
this is an inline emoji:
alert(&#39;hacked&#39;)
"""
@ -67,6 +73,7 @@ defmodule Pleroma.HTMLTest do
this is a link with allowed &quot;rel&quot; attribute: <a href="http://example.com/" rel="tag">example.com</a>
this is a link with not allowed &quot;rel&quot; attribute: <a href="http://example.com/">example.com</a>
this is an image: <img src="http://example.com/image.jpg"/><br/>
this is an inline emoji: <img class="emoji" src="http://example.com/image.jpg"/><br/>
alert(&#39;hacked&#39;)
"""
@ -90,6 +97,15 @@ defmodule Pleroma.HTMLTest do
HTML.filter_tags(@html_span_class_sample, Pleroma.HTML.Scrubber.TwitterText)
end
test "does not allow images with invalid classes" do
expected = """
<img src="http://example.com/image.jpg"/>
"""
assert expected ==
HTML.filter_tags(@html_stillimage_sample, Pleroma.HTML.Scrubber.TwitterText)
end
test "does allow microformats" do
expected = """
<span class="h-card"><a class="u-url mention">@<span>foo</span></a></span>
@ -121,6 +137,7 @@ defmodule Pleroma.HTMLTest do
this is a link with allowed &quot;rel&quot; attribute: <a href="http://example.com/" rel="tag">example.com</a>
this is a link with not allowed &quot;rel&quot; attribute: <a href="http://example.com/">example.com</a>
this is an image: <img src="http://example.com/image.jpg"/><br/>
this is an inline emoji: <img class="emoji" src="http://example.com/image.jpg"/><br/>
alert(&#39;hacked&#39;)
"""
@ -143,6 +160,15 @@ defmodule Pleroma.HTMLTest do
assert expected == HTML.filter_tags(@html_span_class_sample, Pleroma.HTML.Scrubber.Default)
end
test "does not allow images with invalid classes" do
expected = """
<img src="http://example.com/image.jpg"/>
"""
assert expected ==
HTML.filter_tags(@html_stillimage_sample, Pleroma.HTML.Scrubber.TwitterText)
end
test "does allow microformats" do
expected = """
<span class="h-card"><a class="u-url mention">@<span>foo</span></a></span>

View File

@ -507,6 +507,25 @@ defmodule Pleroma.NotificationTest do
end
end
describe "destroy_multiple_from_types/2" do
test "clears all notifications of a certain type for a given user" do
report_activity = insert(:report_activity)
user1 = insert(:user, is_moderator: true, is_admin: true)
user2 = insert(:user, is_moderator: true, is_admin: true)
{:ok, _} = Notification.create_notifications(report_activity)
{:ok, _} =
CommonAPI.post(user2, %{
status: "hey @#{user1.nickname} !"
})
Notification.destroy_multiple_from_types(user1, ["pleroma:report"])
assert [%Pleroma.Notification{type: "mention"}] = Notification.for_user(user1)
assert [%Pleroma.Notification{type: "pleroma:report"}] = Notification.for_user(user2)
end
end
describe "set_read_up_to()" do
test "it sets all notifications as read up to a specified notification ID" do
user = insert(:user)

View File

@ -109,6 +109,11 @@ defmodule Pleroma.SignatureTest do
{:ok, "https://example.com/users/1234"}
end
test "it deduces the actor id for gotoSocial" do
assert Signature.key_id_to_actor_id("https://example.com/users/1234/main-key") ==
{:ok, "https://example.com/users/1234"}
end
test "it calls webfinger for 'acct:' accounts" do
with_mock(Pleroma.Web.WebFinger,
finger: fn _ -> %{"ap_id" => "https://gensokyo.2hu/users/raymoo"} end

View File

@ -5,6 +5,7 @@
defmodule Pleroma.UserTest do
alias Pleroma.Activity
alias Pleroma.Builders.UserBuilder
alias Pleroma.Notification
alias Pleroma.Object
alias Pleroma.Repo
alias Pleroma.Tests.ObanHelpers
@ -2123,6 +2124,26 @@ defmodule Pleroma.UserTest do
assert {:ok, user} = Cachex.get(:user_cache, "ap_id:#{user.ap_id}")
assert %User{bio: "test-bio"} = User.get_cached_by_ap_id(user.ap_id)
end
test "removes report notifs when user isn't superuser any more" do
report_activity = insert(:report_activity)
user = insert(:user, is_moderator: true, is_admin: true)
{:ok, _} = Notification.create_notifications(report_activity)
assert [%Pleroma.Notification{type: "pleroma:report"}] = Notification.for_user(user)
{:ok, user} = user |> User.admin_api_update(%{is_moderator: false})
# is still superuser because still admin
assert [%Pleroma.Notification{type: "pleroma:report"}] = Notification.for_user(user)
{:ok, user} = user |> User.admin_api_update(%{is_moderator: true, is_admin: false})
# is still superuser because still moderator
assert [%Pleroma.Notification{type: "pleroma:report"}] = Notification.for_user(user)
{:ok, user} = user |> User.admin_api_update(%{is_moderator: false})
# is not a superuser any more
assert [] = Notification.for_user(user)
end
end
describe "following/followers synchronization" do

View File

@ -32,4 +32,17 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNotePageValidatorTest
%{valid?: true} = ArticleNotePageValidator.cast_and_validate(note)
end
end
test "a Note without replies/first/items validates" do
insert(:user, ap_id: "https://mastodon.social/users/emelie")
note =
"test/fixtures/tesla_mock/status.emelie.json"
|> File.read!()
|> Jason.decode!()
|> pop_in(["replies", "first", "items"])
|> elem(1)
%{valid?: true} = ArticleNotePageValidator.cast_and_validate(note)
end
end

View File

@ -27,6 +27,46 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidatorTest do
assert attachment.mediaType == "application/octet-stream"
end
test "works with an unknown but valid mime type" do
attachment = %{
"mediaType" => "x-custom/x-type",
"type" => "Document",
"url" => "https://example.org"
}
assert {:ok, attachment} =
AttachmentValidator.cast_and_validate(attachment)
|> Ecto.Changeset.apply_action(:insert)
assert attachment.mediaType == "x-custom/x-type"
end
test "works with invalid mime types" do
attachment = %{
"mediaType" => "x-customx-type",
"type" => "Document",
"url" => "https://example.org"
}
assert {:ok, attachment} =
AttachmentValidator.cast_and_validate(attachment)
|> Ecto.Changeset.apply_action(:insert)
assert attachment.mediaType == "application/octet-stream"
attachment = %{
"mediaType" => "https://example.org",
"type" => "Document",
"url" => "https://example.org"
}
assert {:ok, attachment} =
AttachmentValidator.cast_and_validate(attachment)
|> Ecto.Changeset.apply_action(:insert)
assert attachment.mediaType == "application/octet-stream"
end
test "it turns mastodon attachments into our attachments" do
attachment = %{
"url" =>

View File

@ -1664,21 +1664,21 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|> get("/api/v1/mutes")
|> json_response_and_validate_schema(200)
assert [id1, id2, id3] == Enum.map(result, & &1["id"])
assert [id3, id2, id1] == Enum.map(result, & &1["id"])
result =
conn
|> get("/api/v1/mutes?limit=1")
|> json_response_and_validate_schema(200)
assert [%{"id" => ^id1}] = result
assert [%{"id" => ^id3}] = result
result =
conn
|> get("/api/v1/mutes?since_id=#{id1}")
|> json_response_and_validate_schema(200)
assert [%{"id" => ^id2}, %{"id" => ^id3}] = result
assert [%{"id" => ^id3}, %{"id" => ^id2}] = result
result =
conn
@ -1692,7 +1692,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|> get("/api/v1/mutes?since_id=#{id1}&limit=1")
|> json_response_and_validate_schema(200)
assert [%{"id" => ^id2}] = result
assert [%{"id" => ^id3}] = result
end
test "list of mutes with with_relationships parameter" do
@ -1711,7 +1711,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
assert [
%{
"id" => ^id1,
"id" => ^id3,
"pleroma" => %{"relationship" => %{"muting" => true, "followed_by" => true}}
},
%{
@ -1719,7 +1719,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
"pleroma" => %{"relationship" => %{"muting" => true, "followed_by" => true}}
},
%{
"id" => ^id3,
"id" => ^id1,
"pleroma" => %{"relationship" => %{"muting" => true, "followed_by" => true}}
}
] =
@ -1744,7 +1744,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|> get("/api/v1/blocks")
|> json_response_and_validate_schema(200)
assert [id1, id2, id3] == Enum.map(result, & &1["id"])
assert [id3, id2, id1] == Enum.map(result, & &1["id"])
result =
conn
@ -1752,7 +1752,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|> get("/api/v1/blocks?limit=1")
|> json_response_and_validate_schema(200)
assert [%{"id" => ^id1}] = result
assert [%{"id" => ^id3}] = result
result =
conn
@ -1760,7 +1760,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|> get("/api/v1/blocks?since_id=#{id1}")
|> json_response_and_validate_schema(200)
assert [%{"id" => ^id2}, %{"id" => ^id3}] = result
assert [%{"id" => ^id3}, %{"id" => ^id2}] = result
result =
conn
@ -1776,6 +1776,30 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|> get("/api/v1/blocks?since_id=#{id1}&limit=1")
|> json_response_and_validate_schema(200)
assert [%{"id" => ^id2}] = result
assert [%{"id" => ^id3}] = result
conn_res =
conn
|> assign(:user, user)
|> get("/api/v1/blocks?limit=2")
next_url =
~r{<.+?(?<link>/api[^>]+)>; rel=\"next\"}
|> Regex.named_captures(get_resp_header(conn_res, "link") |> Enum.at(0))
|> Map.get("link")
result =
conn_res
|> json_response_and_validate_schema(200)
assert [%{"id" => ^id3}, %{"id" => ^id2}] = result
result =
conn
|> assign(:user, user)
|> get(next_url)
|> json_response_and_validate_schema(200)
assert [%{"id" => ^id1}] = result
end
end

View File

@ -885,7 +885,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do
end
end
describe "hashtag timeline handling of :restrict_unauthenticated setting" do
describe "hashtag timeline handling of restrict_unauthenticated setting" do
setup do
user = insert(:user)
{:ok, activity1} = CommonAPI.post(user, %{status: "test #tag1"})

View File

@ -10,11 +10,14 @@ defmodule Pleroma.Web.MediaProxy.Invalidation.ScriptTest do
test "it logs error when script is not found" do
assert capture_log(fn ->
assert Invalidation.Script.purge(
["http://example.com/media/example.jpg"],
script_path: "./example"
) == {:error, "%ErlangError{original: :enoent}"}
end) =~ "Error while cache purge: %ErlangError{original: :enoent}"
assert {:error, msg} =
Invalidation.Script.purge(
["http://example.com/media/example.jpg"],
script_path: "./example"
)
assert msg =~ ~r/%ErlangError{original: :enoent(, reason: nil)?}/
end) =~ ~r/Error while cache purge: %ErlangError{original: :enoent(, reason: nil)?}/
capture_log(fn ->
assert Invalidation.Script.purge(