Merge branch 'develop' of https://git.pleroma.social/pleroma/pleroma into emr_develop

This commit is contained in:
a1batross 2020-11-12 18:10:52 +01:00
commit 8a6e69856d
52 changed files with 803 additions and 643 deletions

View File

@ -17,6 +17,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Account backup
- Configuration: Add `:instance, autofollowing_nicknames` setting to provide a way to make accounts automatically follow new users that register on the local Pleroma instance.
- Ability to view remote timelines, with ex. `/api/v1/timelines/public?instance=lain.com` and streams `public:remote` and `public:remote:media`
- The site title is now injected as a `title` tag like preloads or metadata.
### Changed
@ -32,6 +33,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Minimum lifetime for ephmeral activities changed to 10 minutes and made configurable (`:min_lifetime` option).
- Introduced optional dependencies on `ffmpeg`, `ImageMagick`, `exiftool` software packages. Please refer to `docs/installation/optional/media_graphics_packages.md`.
- Polls now always return a `voters_count`, even if they are single-choice
- Admin Emails: The ap id is used as the user link in emails now.
<details>
<summary>API Changes</summary>

View File

@ -1,5 +1,4 @@
use Mix.Config
alias Pleroma.Docs.Generator
websocket_config = [
path: "/websocket",
@ -1555,298 +1554,6 @@ config :pleroma, :config_description, [
}
]
},
%{
group: :pleroma,
key: :mrf,
tab: :mrf,
label: "MRF",
type: :group,
description: "General MRF settings",
children: [
%{
key: :policies,
type: [:module, {:list, :module}],
description:
"A list of MRF policies enabled. Module names are shortened (removed leading `Pleroma.Web.ActivityPub.MRF.` part), but on adding custom module you need to use full name.",
suggestions: {:list_behaviour_implementations, Pleroma.Web.ActivityPub.MRF}
},
%{
key: :transparency,
label: "MRF transparency",
type: :boolean,
description:
"Make the content of your Message Rewrite Facility settings public (via nodeinfo)"
},
%{
key: :transparency_exclusions,
label: "MRF transparency exclusions",
type: {:list, :string},
description:
"Exclude specific instance names from MRF transparency. The use of the exclusions feature will be disclosed in nodeinfo as a boolean value.",
suggestions: [
"exclusion.com"
]
}
]
},
%{
group: :pleroma,
key: :mrf_simple,
tab: :mrf,
related_policy: "Pleroma.Web.ActivityPub.MRF.SimplePolicy",
label: "MRF Simple",
type: :group,
description: "Simple ingress policies",
children: [
%{
key: :media_removal,
type: {:list, :string},
description: "List of instances to strip media attachments from",
suggestions: ["example.com", "*.example.com"]
},
%{
key: :media_nsfw,
label: "Media NSFW",
type: {:list, :string},
description: "List of instances to tag all media as NSFW (sensitive) from",
suggestions: ["example.com", "*.example.com"]
},
%{
key: :federated_timeline_removal,
type: {:list, :string},
description:
"List of instances to remove from the Federated (aka The Whole Known Network) Timeline",
suggestions: ["example.com", "*.example.com"]
},
%{
key: :reject,
type: {:list, :string},
description: "List of instances to reject activities from (except deletes)",
suggestions: ["example.com", "*.example.com"]
},
%{
key: :accept,
type: {:list, :string},
description: "List of instances to only accept activities from (except deletes)",
suggestions: ["example.com", "*.example.com"]
},
%{
key: :followers_only,
type: {:list, :string},
description: "Force posts from the given instances to be visible by followers only",
suggestions: ["example.com", "*.example.com"]
},
%{
key: :report_removal,
type: {:list, :string},
description: "List of instances to reject reports from",
suggestions: ["example.com", "*.example.com"]
},
%{
key: :avatar_removal,
type: {:list, :string},
description: "List of instances to strip avatars from",
suggestions: ["example.com", "*.example.com"]
},
%{
key: :banner_removal,
type: {:list, :string},
description: "List of instances to strip banners from",
suggestions: ["example.com", "*.example.com"]
},
%{
key: :reject_deletes,
type: {:list, :string},
description: "List of instances to reject deletions from",
suggestions: ["example.com", "*.example.com"]
}
]
},
%{
group: :pleroma,
key: :mrf_activity_expiration,
tab: :mrf,
related_policy: "Pleroma.Web.ActivityPub.MRF.ActivityExpirationPolicy",
label: "MRF Activity Expiration Policy",
type: :group,
description: "Adds automatic expiration to all local activities",
children: [
%{
key: :days,
type: :integer,
description: "Default global expiration time for all local activities (in days)",
suggestions: [90, 365]
}
]
},
%{
group: :pleroma,
key: :mrf_subchain,
tab: :mrf,
related_policy: "Pleroma.Web.ActivityPub.MRF.SubchainPolicy",
label: "MRF Subchain",
type: :group,
description:
"This policy processes messages through an alternate pipeline when a given message matches certain criteria." <>
" All criteria are configured as a map of regular expressions to lists of policy modules.",
children: [
%{
key: :match_actor,
type: {:map, {:list, :string}},
description: "Matches a series of regular expressions against the actor field",
suggestions: [
%{
~r/https:\/\/example.com/s => [Pleroma.Web.ActivityPub.MRF.DropPolicy]
}
]
}
]
},
%{
group: :pleroma,
key: :mrf_rejectnonpublic,
tab: :mrf,
related_policy: "Pleroma.Web.ActivityPub.MRF.RejectNonPublic",
description: "RejectNonPublic drops posts with non-public visibility settings.",
label: "MRF Reject Non Public",
type: :group,
children: [
%{
key: :allow_followersonly,
label: "Allow followers-only",
type: :boolean,
description: "Whether to allow followers-only posts"
},
%{
key: :allow_direct,
type: :boolean,
description: "Whether to allow direct messages"
}
]
},
%{
group: :pleroma,
key: :mrf_hellthread,
tab: :mrf,
related_policy: "Pleroma.Web.ActivityPub.MRF.HellthreadPolicy",
label: "MRF Hellthread",
type: :group,
description: "Block messages with excessive user mentions",
children: [
%{
key: :delist_threshold,
type: :integer,
description:
"Number of mentioned users after which the message gets removed from timelines and" <>
"disables notifications. Set to 0 to disable.",
suggestions: [10]
},
%{
key: :reject_threshold,
type: :integer,
description:
"Number of mentioned users after which the messaged gets rejected. Set to 0 to disable.",
suggestions: [20]
}
]
},
%{
group: :pleroma,
key: :mrf_keyword,
tab: :mrf,
related_policy: "Pleroma.Web.ActivityPub.MRF.KeywordPolicy",
label: "MRF Keyword",
type: :group,
description:
"Reject or Word-Replace messages matching a keyword or [Regex](https://hexdocs.pm/elixir/Regex.html).",
children: [
%{
key: :reject,
type: {:list, :string},
description: """
A list of patterns which result in message being rejected.
Each pattern can be a string or [Regex](https://hexdocs.pm/elixir/Regex.html) in the format of `~r/PATTERN/`.
""",
suggestions: ["foo", ~r/foo/iu]
},
%{
key: :federated_timeline_removal,
type: {:list, :string},
description: """
A list of patterns which result in message being removed from federated timelines (a.k.a unlisted).
Each pattern can be a string or [Regex](https://hexdocs.pm/elixir/Regex.html) in the format of `~r/PATTERN/`.
""",
suggestions: ["foo", ~r/foo/iu]
},
%{
key: :replace,
type: {:list, :tuple},
description: """
**Pattern**: a string or [Regex](https://hexdocs.pm/elixir/Regex.html) in the format of `~r/PATTERN/`.
**Replacement**: a string. Leaving the field empty is permitted.
"""
}
]
},
%{
group: :pleroma,
key: :mrf_mention,
tab: :mrf,
related_policy: "Pleroma.Web.ActivityPub.MRF.MentionPolicy",
label: "MRF Mention",
type: :group,
description: "Block messages which mention a specific user",
children: [
%{
key: :actors,
type: {:list, :string},
description: "A list of actors for which any post mentioning them will be dropped",
suggestions: ["actor1", "actor2"]
}
]
},
%{
group: :pleroma,
key: :mrf_vocabulary,
tab: :mrf,
related_policy: "Pleroma.Web.ActivityPub.MRF.VocabularyPolicy",
label: "MRF Vocabulary",
type: :group,
description: "Filter messages which belong to certain activity vocabularies",
children: [
%{
key: :accept,
type: {:list, :string},
description:
"A list of ActivityStreams terms to accept. If empty, all supported messages are accepted.",
suggestions: ["Create", "Follow", "Mention", "Announce", "Like"]
},
%{
key: :reject,
type: {:list, :string},
description:
"A list of ActivityStreams terms to reject. If empty, no messages are rejected.",
suggestions: ["Create", "Follow", "Mention", "Announce", "Like"]
}
]
},
# %{
# group: :pleroma,
# key: :mrf_user_allowlist,
# tab: :mrf,
# related_policy: "Pleroma.Web.ActivityPub.MRF.UserAllowListPolicy",
# type: :map,
# description:
# "The keys in this section are the domain names that the policy should apply to." <>
# " Each key should be assigned a list of users that should be allowed through by their ActivityPub ID",
# suggestions: [
# %{"example.org" => ["https://example.org/users/admin"]}
# ]
# ]
# },
%{
group: :pleroma,
key: :media_proxy,
@ -3159,22 +2866,6 @@ config :pleroma, :config_description, [
}
]
},
%{
group: :pleroma,
key: :mrf_normalize_markup,
tab: :mrf,
related_policy: "Pleroma.Web.ActivityPub.MRF.NormalizeMarkup",
label: "MRF Normalize Markup",
description: "MRF NormalizeMarkup settings. Scrub configured hypertext markup.",
type: :group,
children: [
%{
key: :scrub_policy,
type: :module,
suggestions: [Pleroma.HTML.Scrubber.Default]
}
]
},
%{
group: :pleroma,
key: Pleroma.User,
@ -3364,33 +3055,6 @@ config :pleroma, :config_description, [
}
]
},
%{
group: :pleroma,
key: :mrf_object_age,
tab: :mrf,
related_policy: "Pleroma.Web.ActivityPub.MRF.ObjectAgePolicy",
label: "MRF Object Age",
type: :group,
description:
"Rejects or delists posts based on their timestamp deviance from your server's clock.",
children: [
%{
key: :threshold,
type: :integer,
description: "Required age (in seconds) of a post before actions are taken.",
suggestions: [172_800]
},
%{
key: :actions,
type: {:list, :atom},
description:
"A list of actions to apply to the post. `:delist` removes the post from public timelines; " <>
"`:strip_followers` removes followers from the ActivityPub recipient list ensuring they won't be delivered to home timelines; " <>
"`:reject` rejects the message entirely",
suggestions: [:delist, :strip_followers, :reject]
}
]
},
%{
group: :pleroma,
key: :modules,

View File

@ -1,9 +0,0 @@
# Generate release environment file
```sh tab="OTP"
./bin/pleroma_ctl release_env gen
```
```sh tab="From Source"
mix pleroma.release_env gen
```

View File

@ -21,3 +21,26 @@ This document contains notes and guidelines for Pleroma developers.
## Auth-related configuration, OAuth consumer mode etc.
See `Authentication` section of [the configuration cheatsheet](configuration/cheatsheet.md#authentication).
## MRF policies descriptions
If MRF policy depends on config, it can be added into MRF tab to adminFE by adding `config_description/0` method, which returns map with special structure.
Example:
```elixir
%{
key: :mrf_activity_expiration,
related_policy: "Pleroma.Web.ActivityPub.MRF.ActivityExpirationPolicy",
label: "MRF Activity Expiration Policy",
description: "Adds automatic expiration to all local activities",
children: [
%{
key: :days,
type: :integer,
description: "Default global expiration time for all local activities (in days)",
suggestions: [90, 365]
}
]
}
```

View File

@ -182,7 +182,6 @@ sudo cp /opt/pleroma/installation/pleroma.service /etc/systemd/system/pleroma.se
```
* Edit the service file and make sure that all paths fit your installation
* Check that `EnvironmentFile` contains the correct path to the env file. Or generate the env file: `sudo -Hu pleroma mix pleroma.release_env gen`
* Enable and start `pleroma.service`:
```shell

View File

@ -149,9 +149,6 @@ chown -R pleroma /etc/pleroma
# Run the config generator
su pleroma -s $SHELL -lc "./bin/pleroma_ctl instance gen --output /etc/pleroma/config.exs --output-psql /tmp/setup_db.psql"
# Run the environment file generator.
su pleroma -s $SHELL -lc "./bin/pleroma_ctl release_env gen"
# Create the postgres database
su postgres -s $SHELL -lc "psql -f /tmp/setup_db.psql"

View File

@ -8,7 +8,6 @@ pidfile="/var/run/pleroma.pid"
directory=/opt/pleroma
healthcheck_delay=60
healthcheck_timer=30
export $(cat /opt/pleroma/config/pleroma.env)
: ${pleroma_port:-4000}

View File

@ -17,8 +17,6 @@ Environment="MIX_ENV=prod"
Environment="HOME=/var/lib/pleroma"
; Path to the folder containing the Pleroma installation.
WorkingDirectory=/opt/pleroma
; Path to the environment file. the file contains RELEASE_COOKIE and etc
EnvironmentFile=/opt/pleroma/config/pleroma.env
; Path to the Mix binary.
ExecStart=/usr/bin/mix phx.server

View File

@ -36,9 +36,7 @@ defmodule Mix.Tasks.Pleroma.Instance do
listen_port: :string,
strip_uploads: :string,
anonymize_uploads: :string,
dedupe_uploads: :string,
skip_release_env: :boolean,
release_env_file: :string
dedupe_uploads: :string
],
aliases: [
o: :output,
@ -243,24 +241,6 @@ defmodule Mix.Tasks.Pleroma.Instance do
write_robots_txt(static_dir, indexable, template_dir)
if Keyword.get(options, :skip_release_env, false) do
shell_info("""
Release environment file is skip. Please generate the release env file before start.
`MIX_ENV=#{Mix.env()} mix pleroma.release_env gen`
""")
else
shell_info("Generation the environment file:")
release_env_args =
with path when not is_nil(path) <- Keyword.get(options, :release_env_file) do
["gen", "--path", path]
else
_ -> ["gen"]
end
Mix.Tasks.Pleroma.ReleaseEnv.run(release_env_args)
end
shell_info(
"\n All files successfully written! Refer to the installation instructions for your platform for next steps."
)

View File

@ -1,76 +0,0 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Mix.Tasks.Pleroma.ReleaseEnv do
use Mix.Task
import Mix.Pleroma
@shortdoc "Generate Pleroma environment file."
@moduledoc File.read!("docs/administration/CLI_tasks/release_environments.md")
def run(["gen" | rest]) do
{options, [], []} =
OptionParser.parse(
rest,
strict: [
force: :boolean,
path: :string
],
aliases: [
p: :path,
f: :force
]
)
file_path =
get_option(
options,
:path,
"Environment file path",
"./config/pleroma.env"
)
env_path = Path.expand(file_path)
proceed? =
if File.exists?(env_path) do
get_option(
options,
:force,
"Environment file already exists. Do you want to overwrite the #{env_path} file? (y/n)",
"n"
) === "y"
else
true
end
if proceed? do
case do_generate(env_path) do
{:error, reason} ->
shell_error(
File.Error.message(%{action: "write to file", reason: reason, path: env_path})
)
_ ->
shell_info("\nThe file generated: #{env_path}.\n")
shell_info("""
WARNING: before start pleroma app please make sure to make the file read-only and non-modifiable.
Example:
chmod 0444 #{file_path}
chattr +i #{file_path}
""")
end
else
shell_info("\nThe file is exist. #{env_path}.\n")
end
end
def do_generate(path) do
content = "RELEASE_COOKIE=#{Base.encode32(:crypto.strong_rand_bytes(32))}"
File.mkdir_p!(Path.dirname(path))
File.write(path, content)
end
end

View File

@ -11,7 +11,11 @@ defmodule Pleroma.Docs.JSON do
@spec compile :: :ok
def compile do
:persistent_term.put(@term, Pleroma.Docs.Generator.convert_to_strings(@raw_descriptions))
descriptions =
Pleroma.Web.ActivityPub.MRF.config_descriptions()
|> Enum.reduce(@raw_descriptions, fn description, acc -> [description | acc] end)
:persistent_term.put(@term, Pleroma.Docs.Generator.convert_to_strings(descriptions))
end
@spec compiled_descriptions :: Map.t()

View File

@ -18,10 +18,6 @@ defmodule Pleroma.Emails.AdminEmail do
Keyword.get(instance_config(), :notify_email, instance_config()[:email])
end
defp user_url(user) do
Helpers.user_feed_url(Pleroma.Web.Endpoint, :feed_redirect, user.id)
end
def test_email(mail_to \\ nil) do
html_body = """
<h3>Instance Test Email</h3>
@ -69,8 +65,8 @@ defmodule Pleroma.Emails.AdminEmail do
end
html_body = """
<p>Reported by: <a href="#{user_url(reporter)}">#{reporter.nickname}</a></p>
<p>Reported Account: <a href="#{user_url(account)}">#{account.nickname}</a></p>
<p>Reported by: <a href="#{reporter.ap_id}">#{reporter.nickname}</a></p>
<p>Reported Account: <a href="#{account.ap_id}">#{account.nickname}</a></p>
#{comment_html}
#{statuses_html}
<p>
@ -86,7 +82,7 @@ defmodule Pleroma.Emails.AdminEmail do
def new_unapproved_registration(to, account) do
html_body = """
<p>New account for review: <a href="#{user_url(account)}">@#{account.nickname}</a></p>
<p>New account for review: <a href="#{account.ap_id}">@#{account.nickname}</a></p>
<blockquote>#{HTML.strip_tags(account.registration_reason)}</blockquote>
<a href="#{Pleroma.Web.base_url()}/pleroma/admin/#/users/#{account.id}/">Visit AdminFE</a>
"""

View File

@ -232,8 +232,24 @@ defmodule Pleroma.Object.Fetcher do
|> sign_fetch(id, date)
case HTTP.get(id, headers) do
{:ok, %{body: body, status: code}} when code in 200..299 ->
{:ok, body}
{:ok, %{body: body, status: code, headers: headers}} when code in 200..299 ->
case List.keyfind(headers, "content-type", 0) do
{_, content_type} ->
case Plug.Conn.Utils.media_type(content_type) do
{:ok, "application", "activity+json", _} ->
{:ok, body}
{:ok, "application", "ld+json",
%{"profile" => "https://www.w3.org/ns/activitystreams"}} ->
{:ok, body}
_ ->
{:error, {:content_type, content_type}}
end
_ ->
{:error, {:content_type, nil}}
end
{:ok, %{status: code}} when code in [404, 410] ->
{:error, "Object has been deleted"}

View File

@ -3,7 +3,62 @@
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ActivityPub.MRF do
require Logger
@mrf_config_descriptions [
%{
group: :pleroma,
key: :mrf,
tab: :mrf,
label: "MRF",
type: :group,
description: "General MRF settings",
children: [
%{
key: :policies,
type: [:module, {:list, :module}],
description:
"A list of MRF policies enabled. Module names are shortened (removed leading `Pleroma.Web.ActivityPub.MRF.` part), but on adding custom module you need to use full name.",
suggestions: {:list_behaviour_implementations, Pleroma.Web.ActivityPub.MRF}
},
%{
key: :transparency,
label: "MRF transparency",
type: :boolean,
description:
"Make the content of your Message Rewrite Facility settings public (via nodeinfo)"
},
%{
key: :transparency_exclusions,
label: "MRF transparency exclusions",
type: {:list, :string},
description:
"Exclude specific instance names from MRF transparency. The use of the exclusions feature will be disclosed in nodeinfo as a boolean value.",
suggestions: [
"exclusion.com"
]
}
]
}
]
@default_description %{
label: "",
description: ""
}
@required_description_keys [:key, :related_policy]
@callback filter(Map.t()) :: {:ok | :reject, Map.t()}
@callback describe() :: {:ok | :error, Map.t()}
@callback config_description() :: %{
optional(:children) => [map()],
key: atom(),
related_policy: String.t(),
label: String.t(),
description: String.t()
}
@optional_callbacks config_description: 0
def filter(policies, %{} = message) do
policies
@ -51,8 +106,6 @@ defmodule Pleroma.Web.ActivityPub.MRF do
Enum.any?(domains, fn domain -> Regex.match?(domain, host) end)
end
@callback describe() :: {:ok | :error, Map.t()}
def describe(policies) do
{:ok, policy_configs} =
policies
@ -82,4 +135,41 @@ defmodule Pleroma.Web.ActivityPub.MRF do
end
def describe, do: get_policies() |> describe()
def config_descriptions do
Pleroma.Web.ActivityPub.MRF
|> Pleroma.Docs.Generator.list_behaviour_implementations()
|> config_descriptions()
end
def config_descriptions(policies) do
Enum.reduce(policies, @mrf_config_descriptions, fn policy, acc ->
if function_exported?(policy, :config_description, 0) do
description =
@default_description
|> Map.merge(policy.config_description)
|> Map.put(:group, :pleroma)
|> Map.put(:tab, :mrf)
|> Map.put(:type, :group)
if Enum.all?(@required_description_keys, &Map.has_key?(description, &1)) do
[description | acc]
else
Logger.warn(
"#{policy} config description doesn't have one or all required keys #{
inspect(@required_description_keys)
}"
)
acc
end
else
Logger.debug(
"#{policy} is excluded from config descriptions, because does not implement `config_description/0` method."
)
acc
end
end)
end
end

View File

@ -40,4 +40,22 @@ defmodule Pleroma.Web.ActivityPub.MRF.ActivityExpirationPolicy do
_ -> Map.put(activity, "expires_at", expires_at)
end
end
@impl true
def config_description do
%{
key: :mrf_activity_expiration,
related_policy: "Pleroma.Web.ActivityPub.MRF.ActivityExpirationPolicy",
label: "MRF Activity Expiration Policy",
description: "Adds automatic expiration to all local activities",
children: [
%{
key: :days,
type: :integer,
description: "Default global expiration time for all local activities (in days)",
suggestions: [90, 365]
}
]
}
end
end

View File

@ -97,4 +97,31 @@ defmodule Pleroma.Web.ActivityPub.MRF.HellthreadPolicy do
@impl true
def describe,
do: {:ok, %{mrf_hellthread: Pleroma.Config.get(:mrf_hellthread) |> Enum.into(%{})}}
@impl true
def config_description do
%{
key: :mrf_hellthread,
related_policy: "Pleroma.Web.ActivityPub.MRF.HellthreadPolicy",
label: "MRF Hellthread",
description: "Block messages with excessive user mentions",
children: [
%{
key: :delist_threshold,
type: :integer,
description:
"Number of mentioned users after which the message gets removed from timelines and" <>
"disables notifications. Set to 0 to disable.",
suggestions: [10]
},
%{
key: :reject_threshold,
type: :integer,
description:
"Number of mentioned users after which the messaged gets rejected. Set to 0 to disable.",
suggestions: [20]
}
]
}
end
end

View File

@ -126,4 +126,46 @@ defmodule Pleroma.Web.ActivityPub.MRF.KeywordPolicy do
{:ok, %{mrf_keyword: mrf_keyword}}
end
@impl true
def config_description do
%{
key: :mrf_keyword,
related_policy: "Pleroma.Web.ActivityPub.MRF.KeywordPolicy",
label: "MRF Keyword",
description:
"Reject or Word-Replace messages matching a keyword or [Regex](https://hexdocs.pm/elixir/Regex.html).",
children: [
%{
key: :reject,
type: {:list, :string},
description: """
A list of patterns which result in message being rejected.
Each pattern can be a string or [Regex](https://hexdocs.pm/elixir/Regex.html) in the format of `~r/PATTERN/`.
""",
suggestions: ["foo", ~r/foo/iu]
},
%{
key: :federated_timeline_removal,
type: {:list, :string},
description: """
A list of patterns which result in message being removed from federated timelines (a.k.a unlisted).
Each pattern can be a string or [Regex](https://hexdocs.pm/elixir/Regex.html) in the format of `~r/PATTERN/`.
""",
suggestions: ["foo", ~r/foo/iu]
},
%{
key: :replace,
type: {:list, :tuple},
description: """
**Pattern**: a string or [Regex](https://hexdocs.pm/elixir/Regex.html) in the format of `~r/PATTERN/`.
**Replacement**: a string. Leaving the field empty is permitted.
"""
}
]
}
end
end

View File

@ -25,4 +25,22 @@ defmodule Pleroma.Web.ActivityPub.MRF.MentionPolicy do
@impl true
def describe, do: {:ok, %{}}
@impl true
def config_description do
%{
key: :mrf_mention,
related_policy: "Pleroma.Web.ActivityPub.MRF.MentionPolicy",
label: "MRF Mention",
description: "Block messages which mention a specific user",
children: [
%{
key: :actors,
type: {:list, :string},
description: "A list of actors for which any post mentioning them will be dropped",
suggestions: ["actor1", "actor2"]
}
]
}
end
end

View File

@ -8,6 +8,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.NormalizeMarkup do
@behaviour Pleroma.Web.ActivityPub.MRF
@impl true
def filter(%{"type" => "Create", "object" => child_object} = object) do
scrub_policy = Pleroma.Config.get([:mrf_normalize_markup, :scrub_policy])
@ -22,5 +23,23 @@ defmodule Pleroma.Web.ActivityPub.MRF.NormalizeMarkup do
def filter(object), do: {:ok, object}
@impl true
def describe, do: {:ok, %{}}
@impl true
def config_description do
%{
key: :mrf_normalize_markup,
related_policy: "Pleroma.Web.ActivityPub.MRF.NormalizeMarkup",
label: "MRF Normalize Markup",
description: "MRF NormalizeMarkup settings. Scrub configured hypertext markup.",
children: [
%{
key: :scrub_policy,
type: :module,
suggestions: [Pleroma.HTML.Scrubber.Default]
}
]
}
end
end

View File

@ -106,4 +106,32 @@ defmodule Pleroma.Web.ActivityPub.MRF.ObjectAgePolicy do
{:ok, %{mrf_object_age: mrf_object_age}}
end
@impl true
def config_description do
%{
key: :mrf_object_age,
related_policy: "Pleroma.Web.ActivityPub.MRF.ObjectAgePolicy",
label: "MRF Object Age",
description:
"Rejects or delists posts based on their timestamp deviance from your server's clock.",
children: [
%{
key: :threshold,
type: :integer,
description: "Required age (in seconds) of a post before actions are taken.",
suggestions: [172_800]
},
%{
key: :actions,
type: {:list, :atom},
description:
"A list of actions to apply to the post. `:delist` removes the post from public timelines; " <>
"`:strip_followers` removes followers from the ActivityPub recipient list ensuring they won't be delivered to home timelines; " <>
"`:reject` rejects the message entirely",
suggestions: [:delist, :strip_followers, :reject]
}
]
}
end
end

View File

@ -48,4 +48,27 @@ defmodule Pleroma.Web.ActivityPub.MRF.RejectNonPublic do
@impl true
def describe,
do: {:ok, %{mrf_rejectnonpublic: Config.get(:mrf_rejectnonpublic) |> Enum.into(%{})}}
@impl true
def config_description do
%{
key: :mrf_rejectnonpublic,
related_policy: "Pleroma.Web.ActivityPub.MRF.RejectNonPublic",
description: "RejectNonPublic drops posts with non-public visibility settings.",
label: "MRF Reject Non Public",
children: [
%{
key: :allow_followersonly,
label: "Allow followers-only",
type: :boolean,
description: "Whether to allow followers-only posts"
},
%{
key: :allow_direct,
type: :boolean,
description: "Whether to allow direct messages"
}
]
}
end
end

View File

@ -244,4 +244,78 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do
{:ok, %{mrf_simple: mrf_simple}}
end
@impl true
def config_description do
%{
key: :mrf_simple,
related_policy: "Pleroma.Web.ActivityPub.MRF.SimplePolicy",
label: "MRF Simple",
description: "Simple ingress policies",
children: [
%{
key: :media_removal,
type: {:list, :string},
description: "List of instances to strip media attachments from",
suggestions: ["example.com", "*.example.com"]
},
%{
key: :media_nsfw,
label: "Media NSFW",
type: {:list, :string},
description: "List of instances to tag all media as NSFW (sensitive) from",
suggestions: ["example.com", "*.example.com"]
},
%{
key: :federated_timeline_removal,
type: {:list, :string},
description:
"List of instances to remove from the Federated (aka The Whole Known Network) Timeline",
suggestions: ["example.com", "*.example.com"]
},
%{
key: :reject,
type: {:list, :string},
description: "List of instances to reject activities from (except deletes)",
suggestions: ["example.com", "*.example.com"]
},
%{
key: :accept,
type: {:list, :string},
description: "List of instances to only accept activities from (except deletes)",
suggestions: ["example.com", "*.example.com"]
},
%{
key: :followers_only,
type: {:list, :string},
description: "Force posts from the given instances to be visible by followers only",
suggestions: ["example.com", "*.example.com"]
},
%{
key: :report_removal,
type: {:list, :string},
description: "List of instances to reject reports from",
suggestions: ["example.com", "*.example.com"]
},
%{
key: :avatar_removal,
type: {:list, :string},
description: "List of instances to strip avatars from",
suggestions: ["example.com", "*.example.com"]
},
%{
key: :banner_removal,
type: {:list, :string},
description: "List of instances to strip banners from",
suggestions: ["example.com", "*.example.com"]
},
%{
key: :reject_deletes,
type: {:list, :string},
description: "List of instances to reject deletions from",
suggestions: ["example.com", "*.example.com"]
}
]
}
end
end

View File

@ -39,4 +39,28 @@ defmodule Pleroma.Web.ActivityPub.MRF.SubchainPolicy do
@impl true
def describe, do: {:ok, %{}}
@impl true
def config_description do
%{
key: :mrf_subchain,
related_policy: "Pleroma.Web.ActivityPub.MRF.SubchainPolicy",
label: "MRF Subchain",
description:
"This policy processes messages through an alternate pipeline when a given message matches certain criteria." <>
" All criteria are configured as a map of regular expressions to lists of policy modules.",
children: [
%{
key: :match_actor,
type: {:map, {:list, :string}},
description: "Matches a series of regular expressions against the actor field",
suggestions: [
%{
~r/https:\/\/example.com/s => [Pleroma.Web.ActivityPub.MRF.DropPolicy]
}
]
}
]
}
end
end

View File

@ -41,4 +41,25 @@ defmodule Pleroma.Web.ActivityPub.MRF.UserAllowListPolicy do
{:ok, %{mrf_user_allowlist: mrf_user_allowlist}}
end
# TODO: change way of getting settings on `lib/pleroma/web/activity_pub/mrf/user_allow_list_policy.ex:18` to use `hosts` subkey
# @impl true
# def config_description do
# %{
# key: :mrf_user_allowlist,
# related_policy: "Pleroma.Web.ActivityPub.MRF.UserAllowListPolicy",
# description: "Accept-list of users from specified instances",
# children: [
# %{
# key: :hosts,
# type: :map,
# description:
# "The keys in this section are the domain names that the policy should apply to." <>
# " Each key should be assigned a list of users that should be allowed " <>
# "through by their ActivityPub ID",
# suggestions: [%{"example.org" => ["https://example.org/users/admin"]}]
# }
# ]
# }
# end
end

View File

@ -7,6 +7,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.VocabularyPolicy do
@behaviour Pleroma.Web.ActivityPub.MRF
@impl true
def filter(%{"type" => "Undo", "object" => child_message} = message) do
with {:ok, _} <- filter(child_message) do
{:ok, message}
@ -36,6 +37,33 @@ defmodule Pleroma.Web.ActivityPub.MRF.VocabularyPolicy do
def filter(message), do: {:ok, message}
@impl true
def describe,
do: {:ok, %{mrf_vocabulary: Pleroma.Config.get(:mrf_vocabulary) |> Enum.into(%{})}}
@impl true
def config_description do
%{
key: :mrf_vocabulary,
related_policy: "Pleroma.Web.ActivityPub.MRF.VocabularyPolicy",
label: "MRF Vocabulary",
description: "Filter messages which belong to certain activity vocabularies",
children: [
%{
key: :accept,
type: {:list, :string},
description:
"A list of ActivityStreams terms to accept. If empty, all supported messages are accepted.",
suggestions: ["Create", "Follow", "Mention", "Announce", "Like"]
},
%{
key: :reject,
type: {:list, :string},
description:
"A list of ActivityStreams terms to reject. If empty, no messages are rejected.",
suggestions: ["Create", "Follow", "Mention", "Announce", "Like"]
}
]
}
end
end

View File

@ -15,6 +15,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidator do
field(:type, :string)
field(:mediaType, :string, default: "application/octet-stream")
field(:name, :string)
field(:blurhash, :string)
embeds_many :url, UrlObjectValidator, primary_key: false do
field(:type, :string)
@ -41,7 +42,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidator do
|> fix_url()
struct
|> cast(data, [:type, :mediaType, :name])
|> cast(data, [:type, :mediaType, :name, :blurhash])
|> cast_embed(:url, with: &url_changeset/2)
|> validate_inclusion(:type, ~w[Link Document Audio Image Video])
|> validate_required([:type, :mediaType, :url])

View File

@ -252,6 +252,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
}
|> Maps.put_if_present("mediaType", media_type)
|> Maps.put_if_present("name", data["name"])
|> Maps.put_if_present("blurhash", data["blurhash"])
else
nil
end

View File

@ -37,10 +37,11 @@ defmodule Pleroma.Web.Fallback.RedirectController do
tags = build_tags(conn, params)
preloads = preload_data(conn, params)
title = "<title>#{Pleroma.Config.get([:instance, :name])}</title>"
response =
index_content
|> String.replace("<!--server-generated-meta-->", tags <> preloads)
|> String.replace("<!--server-generated-meta-->", tags <> preloads <> title)
conn
|> put_resp_content_type("text/html")
@ -54,10 +55,11 @@ defmodule Pleroma.Web.Fallback.RedirectController do
def redirector_with_preload(conn, params) do
{:ok, index_content} = File.read(index_file_path())
preloads = preload_data(conn, params)
title = "<title>#{Pleroma.Config.get([:instance, :name])}</title>"
response =
index_content
|> String.replace("<!--server-generated-meta-->", preloads)
|> String.replace("<!--server-generated-meta-->", preloads <> title)
conn
|> put_resp_content_type("text/html")

View File

@ -83,7 +83,7 @@ defmodule Pleroma.Web.Feed.FeedView do
def activity_content(_), do: ""
def activity_context(activity), do: activity.data["context"]
def activity_context(activity), do: escape(activity.data["context"])
def attachment_href(attachment) do
attachment["url"]

View File

@ -435,7 +435,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
text_url: href,
type: type,
description: attachment["name"],
pleroma: %{mime_type: media_type}
pleroma: %{mime_type: media_type},
blurhash: attachment["blurhash"]
}
end

View File

@ -12,7 +12,7 @@
<link href="<%= activity_context(@activity) %>" rel="ostatus:conversation"/>
<%= if @data["summary"] do %>
<summary><%= @data["summary"] %></summary>
<summary><%= escape(@data["summary"]) %></summary>
<% end %>
<%= if @activity.local do %>

View File

@ -12,7 +12,7 @@
<link rel="ostatus:conversation"><%= activity_context(@activity) %></link>
<%= if @data["summary"] do %>
<description><%= @data["summary"] %></description>
<description><%= escape(@data["summary"]) %></description>
<% end %>
<%= if @activity.local do %>

View File

@ -1 +1 @@
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1,user-scalable=no"><title>Pleroma</title><!--server-generated-meta--><link rel=icon type=image/png href=/favicon.png><link href=/static/css/app.77b1644622e3bae24b6b.css rel=stylesheet><link href=/static/fontello.1600365488745.css rel=stylesheet></head><body class=hidden><noscript>To use Pleroma, please enable JavaScript.</noscript><div id=app></div><script type=text/javascript src=/static/js/vendors~app.90c4af83c1ae68f4cd95.js></script><script type=text/javascript src=/static/js/app.826c44232e0a76bbd9ba.js></script></body></html>
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1,user-scalable=no"><!--server-generated-meta--><link rel=icon type=image/png href=/favicon.png><link href=/static/css/app.77b1644622e3bae24b6b.css rel=stylesheet><link href=/static/fontello.1600365488745.css rel=stylesheet></head><body class=hidden><noscript>To use Pleroma, please enable JavaScript.</noscript><div id=app></div><script type=text/javascript src=/static/js/vendors~app.90c4af83c1ae68f4cd95.js></script><script type=text/javascript src=/static/js/app.826c44232e0a76bbd9ba.js></script></body></html>

19
test/fixtures/modules/good_mrf.ex vendored Normal file
View File

@ -0,0 +1,19 @@
defmodule Fixtures.Modules.GoodMRF do
@behaviour Pleroma.Web.ActivityPub.MRF
@impl true
def filter(a), do: {:ok, a}
@impl true
def describe, do: %{}
@impl true
def config_description do
%{
key: :good_mrf,
related_policy: "Fixtures.Modules.GoodMRF",
label: "Good MRF",
description: "Some description"
}
end
end

26
test/fixtures/spoofed-object.json vendored Normal file
View File

@ -0,0 +1,26 @@
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://patch.cx/schemas/litepub-0.1.jsonld",
{
"@language": "und"
}
],
"actor": "https://patch.cx/users/rin",
"attachment": [],
"attributedTo": "https://patch.cx/users/rin",
"cc": [
"https://patch.cx/users/rin/followers"
],
"content": "Oracle Corporation (NYSE: ORCL) today announced that it has signed a definitive merger agreement to acquire Pleroma AG (FRA: PLA), for $26.50 per share (approximately $10.3 billion). The transaction has been approved by the boards of directors of both companies and should close by early January.",
"context": "https://patch.cx/contexts/spoof",
"id": "https://patch.cx/objects/spoof",
"published": "2020-10-23T18:02:06.038856Z",
"sensitive": false,
"summary": "Oracle buys Pleroma",
"tag": [],
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"type": "Note"
}

View File

@ -5,8 +5,6 @@
defmodule Mix.Tasks.Pleroma.InstanceTest do
use ExUnit.Case
@release_env_file "./test/pleroma.test.env"
setup do
File.mkdir_p!(tmp_path())
@ -18,8 +16,6 @@ defmodule Mix.Tasks.Pleroma.InstanceTest do
File.rm_rf(Path.join(static_dir, "robots.txt"))
end
if File.exists?(@release_env_file), do: File.rm_rf(@release_env_file)
Pleroma.Config.put([:instance, :static_dir], static_dir)
end)
@ -73,9 +69,7 @@ defmodule Mix.Tasks.Pleroma.InstanceTest do
"--dedupe-uploads",
"n",
"--anonymize-uploads",
"n",
"--release-env-file",
@release_env_file
"n"
])
end
@ -97,9 +91,6 @@ defmodule Mix.Tasks.Pleroma.InstanceTest do
assert generated_config =~ "filters: [Pleroma.Upload.Filter.ExifTool]"
assert File.read!(tmp_path() <> "setup.psql") == generated_setup_psql()
assert File.exists?(Path.expand("./test/instance/static/robots.txt"))
assert File.exists?(@release_env_file)
assert File.read!(@release_env_file) =~ ~r/^RELEASE_COOKIE=.*/
end
defp generated_setup_psql do

View File

@ -1,30 +0,0 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Mix.Tasks.Pleroma.ReleaseEnvTest do
use ExUnit.Case
import ExUnit.CaptureIO, only: [capture_io: 1]
@path "config/pleroma.test.env"
def do_clean do
if File.exists?(@path) do
File.rm_rf(@path)
end
end
setup do
do_clean()
on_exit(fn -> do_clean() end)
:ok
end
test "generate pleroma.env" do
assert capture_io(fn ->
Mix.Tasks.Pleroma.ReleaseEnv.run(["gen", "--path", @path, "--force"])
end) =~ "The file generated"
assert File.read!(@path) =~ "RELEASE_COOKIE="
end
end

View File

@ -19,8 +19,8 @@ defmodule Pleroma.Emails.AdminEmailTest do
AdminEmail.report(to_user, reporter, account, [%{name: "Test", id: "12"}], "Test comment")
status_url = Helpers.o_status_url(Pleroma.Web.Endpoint, :notice, "12")
reporter_url = Helpers.user_feed_url(Pleroma.Web.Endpoint, :feed_redirect, reporter.id)
account_url = Helpers.user_feed_url(Pleroma.Web.Endpoint, :feed_redirect, account.id)
reporter_url = reporter.ap_id
account_url = account.ap_id
assert res.to == [{to_user.name, to_user.email}]
assert res.from == {config[:name], config[:notify_email]}
@ -54,7 +54,7 @@ defmodule Pleroma.Emails.AdminEmailTest do
res = AdminEmail.new_unapproved_registration(to_user, account)
account_url = Helpers.user_feed_url(Pleroma.Web.Endpoint, :feed_redirect, account.id)
account_url = account.ap_id
assert res.to == [{to_user.name, to_user.email}]
assert res.from == {config[:name], config[:notify_email]}

View File

@ -21,6 +21,17 @@ defmodule Pleroma.Object.FetcherTest do
%{method: :get, url: "https://mastodon.example.org/users/userisgone404"} ->
%Tesla.Env{status: 404}
%{
method: :get,
url:
"https://patch.cx/media/03ca3c8b4ac3ddd08bf0f84be7885f2f88de0f709112131a22d83650819e36c2.json"
} ->
%Tesla.Env{
status: 200,
headers: [{"content-type", "application/json"}],
body: File.read!("test/fixtures/spoofed-object.json")
}
env ->
apply(HttpRequestMock, :request, [env])
end)
@ -34,19 +45,22 @@ defmodule Pleroma.Object.FetcherTest do
%{method: :get, url: "https://social.sakamoto.gq/notice/9wTkLEnuq47B25EehM"} ->
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/fetch_mocks/9wTkLEnuq47B25EehM.json")
body: File.read!("test/fixtures/fetch_mocks/9wTkLEnuq47B25EehM.json"),
headers: HttpRequestMock.activitypub_object_headers()
}
%{method: :get, url: "https://social.sakamoto.gq/users/eal"} ->
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/fetch_mocks/eal.json")
body: File.read!("test/fixtures/fetch_mocks/eal.json"),
headers: HttpRequestMock.activitypub_object_headers()
}
%{method: :get, url: "https://busshi.moe/users/tuxcrafting/statuses/104410921027210069"} ->
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/fetch_mocks/104410921027210069.json")
body: File.read!("test/fixtures/fetch_mocks/104410921027210069.json"),
headers: HttpRequestMock.activitypub_object_headers()
}
%{method: :get, url: "https://busshi.moe/users/tuxcrafting"} ->
@ -132,6 +146,13 @@ defmodule Pleroma.Object.FetcherTest do
"http://mastodon.example.org/@admin/99541947525187367"
)
end
test "it does not fetch a spoofed object uploaded on an instance as an attachment" do
assert {:error, _} =
Fetcher.fetch_object_from_id(
"https://patch.cx/media/03ca3c8b4ac3ddd08bf0f84be7885f2f88de0f709112131a22d83650819e36c2.json"
)
end
end
describe "implementation quirks" do

View File

@ -281,7 +281,11 @@ defmodule Pleroma.ObjectTest do
setup do
mock(fn
%{method: :get, url: "https://patch.cx/objects/9a172665-2bc5-452d-8428-2361d4c33b1d"} ->
%Tesla.Env{status: 200, body: File.read!("test/fixtures/tesla_mock/poll_original.json")}
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/poll_original.json"),
headers: HttpRequestMock.activitypub_object_headers()
}
env ->
apply(HttpRequestMock, :request, [env])
@ -315,7 +319,8 @@ defmodule Pleroma.ObjectTest do
mock_modified.(%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/poll_modified.json")
body: File.read!("test/fixtures/tesla_mock/poll_modified.json"),
headers: HttpRequestMock.activitypub_object_headers()
})
updated_object = Object.get_by_id_and_maybe_refetch(object.id, interval: -1)
@ -359,7 +364,8 @@ defmodule Pleroma.ObjectTest do
mock_modified.(%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/poll_modified.json")
body: File.read!("test/fixtures/tesla_mock/poll_modified.json"),
headers: HttpRequestMock.activitypub_object_headers()
})
updated_object = Object.get_by_id_and_maybe_refetch(object.id, interval: 100)
@ -387,7 +393,8 @@ defmodule Pleroma.ObjectTest do
mock_modified.(%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/poll_modified.json")
body: File.read!("test/fixtures/tesla_mock/poll_modified.json"),
headers: HttpRequestMock.activitypub_object_headers()
})
updated_object = Object.get_by_id_and_maybe_refetch(object.id, interval: -1)

View File

@ -1426,19 +1426,25 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
mock(fn env ->
case env.url do
"http://localhost:4001/users/masto_hidden_counters/following" ->
json(%{
"@context" => "https://www.w3.org/ns/activitystreams",
"id" => "http://localhost:4001/users/masto_hidden_counters/followers"
})
json(
%{
"@context" => "https://www.w3.org/ns/activitystreams",
"id" => "http://localhost:4001/users/masto_hidden_counters/followers"
},
headers: HttpRequestMock.activitypub_object_headers()
)
"http://localhost:4001/users/masto_hidden_counters/following?page=1" ->
%Tesla.Env{status: 403, body: ""}
"http://localhost:4001/users/masto_hidden_counters/followers" ->
json(%{
"@context" => "https://www.w3.org/ns/activitystreams",
"id" => "http://localhost:4001/users/masto_hidden_counters/following"
})
json(
%{
"@context" => "https://www.w3.org/ns/activitystreams",
"id" => "http://localhost:4001/users/masto_hidden_counters/following"
},
headers: HttpRequestMock.activitypub_object_headers()
)
"http://localhost:4001/users/masto_hidden_counters/followers?page=1" ->
%Tesla.Env{status: 403, body: ""}
@ -2278,7 +2284,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
Tesla.Mock.mock(fn
%{method: :get, url: "https://princess.cat/users/mewmew"} ->
file = File.read!("test/fixtures/mewmew_no_name.json")
%Tesla.Env{status: 200, body: file}
%Tesla.Env{status: 200, body: file, headers: HttpRequestMock.activitypub_object_headers()}
end)
{:ok, user} = ActivityPub.make_user_from_ap_id("https://princess.cat/users/mewmew")

View File

@ -87,4 +87,20 @@ defmodule Pleroma.Web.ActivityPub.MRFTest do
{:ok, ^expected} = MRF.describe()
end
end
test "config_descriptions/0" do
descriptions = MRF.config_descriptions()
good_mrf = Enum.find(descriptions, fn %{key: key} -> key == :good_mrf end)
assert good_mrf == %{
key: :good_mrf,
related_policy: "Fixtures.Modules.GoodMRF",
label: "Good MRF",
description: "Some description",
group: :pleroma,
tab: :mrf,
type: :group
}
end
end

View File

@ -33,7 +33,8 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidatorTest do
"http://mastodon.example.org/system/media_attachments/files/000/000/002/original/334ce029e7bfb920.jpg",
"type" => "Document",
"name" => nil,
"mediaType" => "image/jpeg"
"mediaType" => "image/jpeg",
"blurhash" => "UD9jJz~VSbR#xT$~%KtQX9R,WAs9RjWBs:of"
}
{:ok, attachment} =
@ -50,6 +51,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidatorTest do
] = attachment.url
assert attachment.mediaType == "image/jpeg"
assert attachment.blurhash == "UD9jJz~VSbR#xT$~%KtQX9R,WAs9RjWBs:of"
end
test "it handles our own uploads" do

View File

@ -60,7 +60,11 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.AnnounceHandlingTest do
Tesla.Mock.mock(fn
%{method: :get} ->
%Tesla.Env{status: 200, body: File.read!("test/fixtures/mastodon-note-object.json")}
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/mastodon-note-object.json"),
headers: HttpRequestMock.activitypub_object_headers()
}
end)
_user = insert(:user, local: false, ap_id: data["actor"])

View File

@ -13,7 +13,11 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.ArticleHandlingTest do
test "Pterotype (Wordpress Plugin) Article" do
Tesla.Mock.mock(fn %{url: "https://wedistribute.org/wp-json/pterotype/v1/actor/-blog"} ->
%Tesla.Env{status: 200, body: File.read!("test/fixtures/tesla_mock/wedistribute-user.json")}
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/wedistribute-user.json"),
headers: HttpRequestMock.activitypub_object_headers()
}
end)
data =
@ -36,13 +40,15 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.ArticleHandlingTest do
%{url: "https://baptiste.gelez.xyz/~/PlumeDevelopment/this-month-in-plume-june-2018/"} ->
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/baptiste.gelex.xyz-article.json")
body: File.read!("test/fixtures/tesla_mock/baptiste.gelex.xyz-article.json"),
headers: HttpRequestMock.activitypub_object_headers()
}
%{url: "https://baptiste.gelez.xyz/@/BaptisteGelez"} ->
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/baptiste.gelex.xyz-user.json")
body: File.read!("test/fixtures/tesla_mock/baptiste.gelex.xyz-user.json"),
headers: HttpRequestMock.activitypub_object_headers()
}
end)
@ -61,7 +67,8 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.ArticleHandlingTest do
Tesla.Mock.mock(fn %{url: "https://prismo.news/@mxb"} ->
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/https___prismo.news__mxb.json")
body: File.read!("test/fixtures/tesla_mock/https___prismo.news__mxb.json"),
headers: HttpRequestMock.activitypub_object_headers()
}
end)

View File

@ -48,7 +48,8 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.AudioHandlingTest do
%{url: "https://channels.tests.funkwhale.audio/federation/actors/compositions"} ->
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/funkwhale_channel.json")
body: File.read!("test/fixtures/tesla_mock/funkwhale_channel.json"),
headers: HttpRequestMock.activitypub_object_headers()
}
end)
@ -69,6 +70,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.AudioHandlingTest do
"mediaType" => "audio/ogg",
"type" => "Link",
"name" => nil,
"blurhash" => nil,
"url" => [
%{
"href" =>

View File

@ -13,13 +13,15 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.EventHandlingTest do
%{url: "https://mobilizon.org/events/252d5816-00a3-4a89-a66f-15bf65c33e39"} ->
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/mobilizon.org-event.json")
body: File.read!("test/fixtures/tesla_mock/mobilizon.org-event.json"),
headers: HttpRequestMock.activitypub_object_headers()
}
%{url: "https://mobilizon.org/@tcit"} ->
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/mobilizon.org-user.json")
body: File.read!("test/fixtures/tesla_mock/mobilizon.org-user.json"),
headers: HttpRequestMock.activitypub_object_headers()
}
end)

View File

@ -54,6 +54,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.VideoHandlingTest do
"type" => "Link",
"mediaType" => "video/mp4",
"name" => nil,
"blurhash" => nil,
"url" => [
%{
"href" =>
@ -76,6 +77,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.VideoHandlingTest do
"type" => "Link",
"mediaType" => "video/mp4",
"name" => nil,
"blurhash" => nil,
"url" => [
%{
"href" =>

View File

@ -20,15 +20,26 @@ defmodule Pleroma.Web.FallbackTest do
end
end
test "GET /*path adds a title", %{conn: conn} do
clear_config([:instance, :name], "a cool title")
assert conn
|> get("/")
|> html_response(200) =~ "<title>a cool title</title>"
end
describe "preloaded data and metadata attached to" do
test "GET /:maybe_nickname_or_id", %{conn: conn} do
clear_config([:instance, :name], "a cool title")
user = insert(:user)
user_missing = get(conn, "/foo")
user_present = get(conn, "/#{user.nickname}")
assert(html_response(user_missing, 200) =~ "<!--server-generated-meta-->")
assert html_response(user_missing, 200) =~ "<!--server-generated-meta-->"
refute html_response(user_present, 200) =~ "<!--server-generated-meta-->"
assert html_response(user_present, 200) =~ "initial-results"
assert html_response(user_present, 200) =~ "<title>a cool title</title>"
end
test "GET /*path", %{conn: conn} do
@ -44,10 +55,13 @@ defmodule Pleroma.Web.FallbackTest do
describe "preloaded data is attached to" do
test "GET /main/public", %{conn: conn} do
clear_config([:instance, :name], "a cool title")
public_page = get(conn, "/main/public")
refute html_response(public_page, 200) =~ "<!--server-generated-meta-->"
assert html_response(public_page, 200) =~ "initial-results"
assert html_response(public_page, 200) =~ "<title>a cool title</title>"
end
test "GET /main/all", %{conn: conn} do

View File

@ -12,16 +12,17 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
alias Pleroma.Object
alias Pleroma.User
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.Feed.FeedView
setup do: clear_config([:static_fe, :enabled], false)
describe "feed" do
setup do: clear_config([:feed])
test "gets an atom feed", %{conn: conn} do
setup do
Config.put(
[:feed, :post_title],
%{max_length: 10, omission: "..."}
%{max_length: 15, omission: "..."}
)
activity = insert(:note_activity)
@ -29,7 +30,8 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
note =
insert(:note,
data: %{
"content" => "This is :moominmamma: note ",
"content" => "This & this is :moominmamma: note ",
"source" => "This & this is :moominmamma: note ",
"attachment" => [
%{
"url" => [
@ -37,7 +39,9 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
]
}
],
"inReplyTo" => activity.data["id"]
"inReplyTo" => activity.data["id"],
"context" => "2hu & as",
"summary" => "2hu & as"
}
)
@ -48,7 +52,7 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
insert(:note,
user: user,
data: %{
"content" => "42 This is :moominmamma: note ",
"content" => "42 & This is :moominmamma: note ",
"inReplyTo" => activity.data["id"]
}
)
@ -56,6 +60,10 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
note_activity2 = insert(:note_activity, note: note2)
object = Object.normalize(note_activity)
[user: user, object: object, max_id: note_activity2.id]
end
test "gets an atom feed", %{conn: conn, user: user, object: object, max_id: max_id} do
resp =
conn
|> put_req_header("accept", "application/atom+xml")
@ -67,13 +75,15 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
|> SweetXml.parse()
|> SweetXml.xpath(~x"//entry/title/text()"l)
assert activity_titles == ['42 This...', 'This is...']
assert resp =~ object.data["content"]
assert activity_titles == ['42 &amp; Thi...', 'This &amp; t...']
assert resp =~ FeedView.escape(object.data["content"])
assert resp =~ FeedView.escape(object.data["summary"])
assert resp =~ FeedView.escape(object.data["context"])
resp =
conn
|> put_req_header("accept", "application/atom+xml")
|> get("/users/#{user.nickname}/feed", %{"max_id" => note_activity2.id})
|> get("/users/#{user.nickname}/feed", %{"max_id" => max_id})
|> response(200)
activity_titles =
@ -81,47 +91,10 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
|> SweetXml.parse()
|> SweetXml.xpath(~x"//entry/title/text()"l)
assert activity_titles == ['This is...']
assert activity_titles == ['This &amp; t...']
end
test "gets a rss feed", %{conn: conn} do
Pleroma.Config.put(
[:feed, :post_title],
%{max_length: 10, omission: "..."}
)
activity = insert(:note_activity)
note =
insert(:note,
data: %{
"content" => "This is :moominmamma: note ",
"attachment" => [
%{
"url" => [
%{"mediaType" => "image/png", "href" => "https://pleroma.gov/image.png"}
]
}
],
"inReplyTo" => activity.data["id"]
}
)
note_activity = insert(:note_activity, note: note)
user = User.get_cached_by_ap_id(note_activity.data["actor"])
note2 =
insert(:note,
user: user,
data: %{
"content" => "42 This is :moominmamma: note ",
"inReplyTo" => activity.data["id"]
}
)
note_activity2 = insert(:note_activity, note: note2)
object = Object.normalize(note_activity)
test "gets a rss feed", %{conn: conn, user: user, object: object, max_id: max_id} do
resp =
conn
|> put_req_header("accept", "application/rss+xml")
@ -133,13 +106,15 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
|> SweetXml.parse()
|> SweetXml.xpath(~x"//item/title/text()"l)
assert activity_titles == ['42 This...', 'This is...']
assert resp =~ object.data["content"]
assert activity_titles == ['42 &amp; Thi...', 'This &amp; t...']
assert resp =~ FeedView.escape(object.data["content"])
assert resp =~ FeedView.escape(object.data["summary"])
assert resp =~ FeedView.escape(object.data["context"])
resp =
conn
|> put_req_header("accept", "application/rss+xml")
|> get("/users/#{user.nickname}/feed.rss", %{"max_id" => note_activity2.id})
|> get("/users/#{user.nickname}/feed.rss", %{"max_id" => max_id})
|> response(200)
activity_titles =
@ -147,7 +122,7 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
|> SweetXml.parse()
|> SweetXml.xpath(~x"//item/title/text()"l)
assert activity_titles == ['This is...']
assert activity_titles == ['This &amp; t...']
end
test "returns 404 for a missing feed", %{conn: conn} do

View File

@ -420,6 +420,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
"href" => "someurl"
}
],
"blurhash" => "UJJ8X[xYW,%Jtq%NNFbXB5j]IVM|9GV=WHRn",
"uuid" => 6
}
@ -431,7 +432,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
preview_url: "someurl",
text_url: "someurl",
description: nil,
pleroma: %{mime_type: "image/png"}
pleroma: %{mime_type: "image/png"},
blurhash: "UJJ8X[xYW,%Jtq%NNFbXB5j]IVM|9GV=WHRn"
}
api_spec = Pleroma.Web.ApiSpec.spec()

View File

@ -5,6 +5,8 @@
defmodule HttpRequestMock do
require Logger
def activitypub_object_headers, do: [{"content-type", "application/activity+json"}]
def request(
%Tesla.Env{
url: url,
@ -34,7 +36,8 @@ defmodule HttpRequestMock do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/https___osada.macgirvin.com_channel_mike.json")
body: File.read!("test/fixtures/tesla_mock/https___osada.macgirvin.com_channel_mike.json"),
headers: activitypub_object_headers()
}}
end
@ -42,7 +45,8 @@ defmodule HttpRequestMock do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/moonman@shitposter.club.json")
body: File.read!("test/fixtures/tesla_mock/moonman@shitposter.club.json"),
headers: activitypub_object_headers()
}}
end
@ -50,7 +54,8 @@ defmodule HttpRequestMock do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/status.emelie.json")
body: File.read!("test/fixtures/tesla_mock/status.emelie.json"),
headers: activitypub_object_headers()
}}
end
@ -66,7 +71,8 @@ defmodule HttpRequestMock do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/emelie.json")
body: File.read!("test/fixtures/tesla_mock/emelie.json"),
headers: activitypub_object_headers()
}}
end
@ -78,7 +84,8 @@ defmodule HttpRequestMock do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/rinpatch.json")
body: File.read!("test/fixtures/tesla_mock/rinpatch.json"),
headers: activitypub_object_headers()
}}
end
@ -86,7 +93,8 @@ defmodule HttpRequestMock do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/poll_attachment.json")
body: File.read!("test/fixtures/tesla_mock/poll_attachment.json"),
headers: activitypub_object_headers()
}}
end
@ -99,7 +107,8 @@ defmodule HttpRequestMock do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/webfinger_emelie.json")
body: File.read!("test/fixtures/tesla_mock/webfinger_emelie.json"),
headers: activitypub_object_headers()
}}
end
@ -112,7 +121,8 @@ defmodule HttpRequestMock do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/mike@osada.macgirvin.com.json")
body: File.read!("test/fixtures/tesla_mock/mike@osada.macgirvin.com.json"),
headers: activitypub_object_headers()
}}
end
@ -190,7 +200,8 @@ defmodule HttpRequestMock do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/lucifermysticus.json")
body: File.read!("test/fixtures/tesla_mock/lucifermysticus.json"),
headers: activitypub_object_headers()
}}
end
@ -198,7 +209,8 @@ defmodule HttpRequestMock do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/https___prismo.news__mxb.json")
body: File.read!("test/fixtures/tesla_mock/https___prismo.news__mxb.json"),
headers: activitypub_object_headers()
}}
end
@ -211,7 +223,8 @@ defmodule HttpRequestMock do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/kaniini@hubzilla.example.org.json")
body: File.read!("test/fixtures/tesla_mock/kaniini@hubzilla.example.org.json"),
headers: activitypub_object_headers()
}}
end
@ -219,7 +232,8 @@ defmodule HttpRequestMock do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/rye.json")
body: File.read!("test/fixtures/tesla_mock/rye.json"),
headers: activitypub_object_headers()
}}
end
@ -227,7 +241,8 @@ defmodule HttpRequestMock do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/rye.json")
body: File.read!("test/fixtures/tesla_mock/rye.json"),
headers: activitypub_object_headers()
}}
end
@ -246,7 +261,8 @@ defmodule HttpRequestMock do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/puckipedia.com.json")
body: File.read!("test/fixtures/tesla_mock/puckipedia.com.json"),
headers: activitypub_object_headers()
}}
end
@ -254,7 +270,8 @@ defmodule HttpRequestMock do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/7even.json")
body: File.read!("test/fixtures/tesla_mock/7even.json"),
headers: activitypub_object_headers()
}}
end
@ -262,7 +279,8 @@ defmodule HttpRequestMock do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/peertube.moe-vid.json")
body: File.read!("test/fixtures/tesla_mock/peertube.moe-vid.json"),
headers: activitypub_object_headers()
}}
end
@ -270,7 +288,8 @@ defmodule HttpRequestMock do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/https___framatube.org_accounts_framasoft.json")
body: File.read!("test/fixtures/tesla_mock/https___framatube.org_accounts_framasoft.json"),
headers: activitypub_object_headers()
}}
end
@ -278,7 +297,8 @@ defmodule HttpRequestMock do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/framatube.org-video.json")
body: File.read!("test/fixtures/tesla_mock/framatube.org-video.json"),
headers: activitypub_object_headers()
}}
end
@ -286,7 +306,8 @@ defmodule HttpRequestMock do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/craigmaloney.json")
body: File.read!("test/fixtures/tesla_mock/craigmaloney.json"),
headers: activitypub_object_headers()
}}
end
@ -294,7 +315,8 @@ defmodule HttpRequestMock do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/peertube-social.json")
body: File.read!("test/fixtures/tesla_mock/peertube-social.json"),
headers: activitypub_object_headers()
}}
end
@ -304,7 +326,8 @@ defmodule HttpRequestMock do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/mobilizon.org-event.json")
body: File.read!("test/fixtures/tesla_mock/mobilizon.org-event.json"),
headers: activitypub_object_headers()
}}
end
@ -312,7 +335,8 @@ defmodule HttpRequestMock do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/mobilizon.org-user.json")
body: File.read!("test/fixtures/tesla_mock/mobilizon.org-user.json"),
headers: activitypub_object_headers()
}}
end
@ -320,7 +344,8 @@ defmodule HttpRequestMock do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/baptiste.gelex.xyz-user.json")
body: File.read!("test/fixtures/tesla_mock/baptiste.gelex.xyz-user.json"),
headers: activitypub_object_headers()
}}
end
@ -328,7 +353,8 @@ defmodule HttpRequestMock do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/baptiste.gelex.xyz-article.json")
body: File.read!("test/fixtures/tesla_mock/baptiste.gelex.xyz-article.json"),
headers: activitypub_object_headers()
}}
end
@ -336,7 +362,8 @@ defmodule HttpRequestMock do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/wedistribute-article.json")
body: File.read!("test/fixtures/tesla_mock/wedistribute-article.json"),
headers: activitypub_object_headers()
}}
end
@ -344,7 +371,8 @@ defmodule HttpRequestMock do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/wedistribute-user.json")
body: File.read!("test/fixtures/tesla_mock/wedistribute-user.json"),
headers: activitypub_object_headers()
}}
end
@ -352,7 +380,8 @@ defmodule HttpRequestMock do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/admin@mastdon.example.org.json")
body: File.read!("test/fixtures/tesla_mock/admin@mastdon.example.org.json"),
headers: activitypub_object_headers()
}}
end
@ -362,7 +391,8 @@ defmodule HttpRequestMock do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/relay@mastdon.example.org.json")
body: File.read!("test/fixtures/tesla_mock/relay@mastdon.example.org.json"),
headers: activitypub_object_headers()
}}
end
@ -482,7 +512,8 @@ defmodule HttpRequestMock do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/pekorino@pawoo.net_host_meta.json")
body: File.read!("test/fixtures/tesla_mock/pekorino@pawoo.net_host_meta.json"),
headers: activitypub_object_headers()
}}
end
@ -543,7 +574,8 @@ defmodule HttpRequestMock do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/mastodon-note-object.json")
body: File.read!("test/fixtures/mastodon-note-object.json"),
headers: activitypub_object_headers()
}}
end
@ -567,7 +599,8 @@ defmodule HttpRequestMock do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/mayumayu.json")
body: File.read!("test/fixtures/tesla_mock/mayumayu.json"),
headers: activitypub_object_headers()
}}
end
@ -580,7 +613,8 @@ defmodule HttpRequestMock do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/mayumayupost.json")
body: File.read!("test/fixtures/tesla_mock/mayumayupost.json"),
headers: activitypub_object_headers()
}}
end
@ -795,7 +829,8 @@ defmodule HttpRequestMock do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/winterdienst_webfinger.json")
body: File.read!("test/fixtures/tesla_mock/winterdienst_webfinger.json"),
headers: activitypub_object_headers()
}}
end
@ -867,12 +902,21 @@ defmodule HttpRequestMock do
end
def get("https://mastodon.social/users/lambadalambda", _, _, _) do
{:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/lambadalambda.json")}}
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/lambadalambda.json"),
headers: activitypub_object_headers()
}}
end
def get("https://apfed.club/channel/indio", _, _, _) do
{:ok,
%Tesla.Env{status: 200, body: File.read!("test/fixtures/tesla_mock/osada-user-indio.json")}}
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/osada-user-indio.json"),
headers: activitypub_object_headers()
}}
end
def get("https://social.heldscal.la/user/23211", _, _, [{"accept", "application/activity+json"}]) do
@ -895,7 +939,8 @@ defmodule HttpRequestMock do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/users_mock/masto_closed_followers.json")
body: File.read!("test/fixtures/users_mock/masto_closed_followers.json"),
headers: activitypub_object_headers()
}}
end
@ -903,7 +948,8 @@ defmodule HttpRequestMock do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/users_mock/masto_closed_followers_page.json")
body: File.read!("test/fixtures/users_mock/masto_closed_followers_page.json"),
headers: activitypub_object_headers()
}}
end
@ -911,7 +957,8 @@ defmodule HttpRequestMock do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/users_mock/masto_closed_following.json")
body: File.read!("test/fixtures/users_mock/masto_closed_following.json"),
headers: activitypub_object_headers()
}}
end
@ -919,7 +966,8 @@ defmodule HttpRequestMock do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/users_mock/masto_closed_following_page.json")
body: File.read!("test/fixtures/users_mock/masto_closed_following_page.json"),
headers: activitypub_object_headers()
}}
end
@ -927,7 +975,8 @@ defmodule HttpRequestMock do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/users_mock/friendica_followers.json")
body: File.read!("test/fixtures/users_mock/friendica_followers.json"),
headers: activitypub_object_headers()
}}
end
@ -935,7 +984,8 @@ defmodule HttpRequestMock do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/users_mock/friendica_following.json")
body: File.read!("test/fixtures/users_mock/friendica_following.json"),
headers: activitypub_object_headers()
}}
end
@ -943,7 +993,8 @@ defmodule HttpRequestMock do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/users_mock/pleroma_followers.json")
body: File.read!("test/fixtures/users_mock/pleroma_followers.json"),
headers: activitypub_object_headers()
}}
end
@ -951,7 +1002,8 @@ defmodule HttpRequestMock do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/users_mock/pleroma_following.json")
body: File.read!("test/fixtures/users_mock/pleroma_following.json"),
headers: activitypub_object_headers()
}}
end
@ -1049,7 +1101,8 @@ defmodule HttpRequestMock do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/https__info.pleroma.site_activity.json")
body: File.read!("test/fixtures/tesla_mock/https__info.pleroma.site_activity.json"),
headers: activitypub_object_headers()
}}
end
@ -1063,7 +1116,8 @@ defmodule HttpRequestMock do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/https__info.pleroma.site_activity2.json")
body: File.read!("test/fixtures/tesla_mock/https__info.pleroma.site_activity2.json"),
headers: activitypub_object_headers()
}}
end
@ -1077,7 +1131,8 @@ defmodule HttpRequestMock do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/https__info.pleroma.site_activity3.json")
body: File.read!("test/fixtures/tesla_mock/https__info.pleroma.site_activity3.json"),
headers: activitypub_object_headers()
}}
end
@ -1110,7 +1165,12 @@ defmodule HttpRequestMock do
end
def get("http://mastodon.example.org/@admin/99541947525187367", _, _, _) do
{:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/mastodon-post-activity.json")}}
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/mastodon-post-activity.json"),
headers: activitypub_object_headers()
}}
end
def get("https://info.pleroma.site/activity4.json", _, _, _) do
@ -1137,7 +1197,8 @@ defmodule HttpRequestMock do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/misskey_poll_no_end_date.json")
body: File.read!("test/fixtures/tesla_mock/misskey_poll_no_end_date.json"),
headers: activitypub_object_headers()
}}
end
@ -1146,11 +1207,21 @@ defmodule HttpRequestMock do
end
def get("https://skippers-bin.com/users/7v1w1r8ce6", _, _, _) do
{:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/tesla_mock/sjw.json")}}
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/sjw.json"),
headers: activitypub_object_headers()
}}
end
def get("https://patch.cx/users/rin", _, _, _) do
{:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/tesla_mock/rin.json")}}
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/rin.json"),
headers: activitypub_object_headers()
}}
end
def get(
@ -1160,12 +1231,20 @@ defmodule HttpRequestMock do
_
) do
{:ok,
%Tesla.Env{status: 200, body: File.read!("test/fixtures/tesla_mock/funkwhale_audio.json")}}
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/funkwhale_audio.json"),
headers: activitypub_object_headers()
}}
end
def get("https://channels.tests.funkwhale.audio/federation/actors/compositions", _, _, _) do
{:ok,
%Tesla.Env{status: 200, body: File.read!("test/fixtures/tesla_mock/funkwhale_channel.json")}}
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/funkwhale_channel.json"),
headers: activitypub_object_headers()
}}
end
def get("http://example.com/rel_me/error", _, _, _) do
@ -1173,7 +1252,12 @@ defmodule HttpRequestMock do
end
def get("https://relay.mastodon.host/actor", _, _, _) do
{:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/relay/relay.json")}}
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/relay/relay.json"),
headers: activitypub_object_headers()
}}
end
def get("http://localhost:4001/", _, "", [{"accept", "text/html"}]) do