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 - 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. - 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` - 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 ### 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). - 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`. - 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 - 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> <details>
<summary>API Changes</summary> <summary>API Changes</summary>

View File

@ -1,5 +1,4 @@
use Mix.Config use Mix.Config
alias Pleroma.Docs.Generator
websocket_config = [ websocket_config = [
path: "/websocket", 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, group: :pleroma,
key: :media_proxy, 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, group: :pleroma,
key: Pleroma.User, 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, group: :pleroma,
key: :modules, 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. ## Auth-related configuration, OAuth consumer mode etc.
See `Authentication` section of [the configuration cheatsheet](configuration/cheatsheet.md#authentication). 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 * 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`: * Enable and start `pleroma.service`:
```shell ```shell

View File

@ -149,9 +149,6 @@ chown -R pleroma /etc/pleroma
# Run the config generator # 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" 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 # Create the postgres database
su postgres -s $SHELL -lc "psql -f /tmp/setup_db.psql" 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 directory=/opt/pleroma
healthcheck_delay=60 healthcheck_delay=60
healthcheck_timer=30 healthcheck_timer=30
export $(cat /opt/pleroma/config/pleroma.env)
: ${pleroma_port:-4000} : ${pleroma_port:-4000}

View File

@ -17,8 +17,6 @@ Environment="MIX_ENV=prod"
Environment="HOME=/var/lib/pleroma" Environment="HOME=/var/lib/pleroma"
; Path to the folder containing the Pleroma installation. ; Path to the folder containing the Pleroma installation.
WorkingDirectory=/opt/pleroma 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. ; Path to the Mix binary.
ExecStart=/usr/bin/mix phx.server ExecStart=/usr/bin/mix phx.server

View File

@ -36,9 +36,7 @@ defmodule Mix.Tasks.Pleroma.Instance do
listen_port: :string, listen_port: :string,
strip_uploads: :string, strip_uploads: :string,
anonymize_uploads: :string, anonymize_uploads: :string,
dedupe_uploads: :string, dedupe_uploads: :string
skip_release_env: :boolean,
release_env_file: :string
], ],
aliases: [ aliases: [
o: :output, o: :output,
@ -243,24 +241,6 @@ defmodule Mix.Tasks.Pleroma.Instance do
write_robots_txt(static_dir, indexable, template_dir) 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( shell_info(
"\n All files successfully written! Refer to the installation instructions for your platform for next steps." "\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 @spec compile :: :ok
def compile do 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 end
@spec compiled_descriptions :: Map.t() @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]) Keyword.get(instance_config(), :notify_email, instance_config()[:email])
end 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 def test_email(mail_to \\ nil) do
html_body = """ html_body = """
<h3>Instance Test Email</h3> <h3>Instance Test Email</h3>
@ -69,8 +65,8 @@ defmodule Pleroma.Emails.AdminEmail do
end end
html_body = """ html_body = """
<p>Reported by: <a href="#{user_url(reporter)}">#{reporter.nickname}</a></p> <p>Reported by: <a href="#{reporter.ap_id}">#{reporter.nickname}</a></p>
<p>Reported Account: <a href="#{user_url(account)}">#{account.nickname}</a></p> <p>Reported Account: <a href="#{account.ap_id}">#{account.nickname}</a></p>
#{comment_html} #{comment_html}
#{statuses_html} #{statuses_html}
<p> <p>
@ -86,7 +82,7 @@ defmodule Pleroma.Emails.AdminEmail do
def new_unapproved_registration(to, account) do def new_unapproved_registration(to, account) do
html_body = """ 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> <blockquote>#{HTML.strip_tags(account.registration_reason)}</blockquote>
<a href="#{Pleroma.Web.base_url()}/pleroma/admin/#/users/#{account.id}/">Visit AdminFE</a> <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) |> sign_fetch(id, date)
case HTTP.get(id, headers) do case HTTP.get(id, headers) do
{:ok, %{body: body, status: code}} when code in 200..299 -> {:ok, %{body: body, status: code, headers: headers}} when code in 200..299 ->
{:ok, body} 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] -> {:ok, %{status: code}} when code in [404, 410] ->
{:error, "Object has been deleted"} {:error, "Object has been deleted"}

View File

@ -3,7 +3,62 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ActivityPub.MRF do 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 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 def filter(policies, %{} = message) do
policies policies
@ -51,8 +106,6 @@ defmodule Pleroma.Web.ActivityPub.MRF do
Enum.any?(domains, fn domain -> Regex.match?(domain, host) end) Enum.any?(domains, fn domain -> Regex.match?(domain, host) end)
end end
@callback describe() :: {:ok | :error, Map.t()}
def describe(policies) do def describe(policies) do
{:ok, policy_configs} = {:ok, policy_configs} =
policies policies
@ -82,4 +135,41 @@ defmodule Pleroma.Web.ActivityPub.MRF do
end end
def describe, do: get_policies() |> describe() 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 end

View File

@ -40,4 +40,22 @@ defmodule Pleroma.Web.ActivityPub.MRF.ActivityExpirationPolicy do
_ -> Map.put(activity, "expires_at", expires_at) _ -> Map.put(activity, "expires_at", expires_at)
end end
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 end

View File

@ -97,4 +97,31 @@ defmodule Pleroma.Web.ActivityPub.MRF.HellthreadPolicy do
@impl true @impl true
def describe, def describe,
do: {:ok, %{mrf_hellthread: Pleroma.Config.get(:mrf_hellthread) |> Enum.into(%{})}} 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 end

View File

@ -126,4 +126,46 @@ defmodule Pleroma.Web.ActivityPub.MRF.KeywordPolicy do
{:ok, %{mrf_keyword: mrf_keyword}} {:ok, %{mrf_keyword: mrf_keyword}}
end 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 end

View File

@ -25,4 +25,22 @@ defmodule Pleroma.Web.ActivityPub.MRF.MentionPolicy do
@impl true @impl true
def describe, do: {:ok, %{}} 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 end

View File

@ -8,6 +8,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.NormalizeMarkup do
@behaviour Pleroma.Web.ActivityPub.MRF @behaviour Pleroma.Web.ActivityPub.MRF
@impl true
def filter(%{"type" => "Create", "object" => child_object} = object) do def filter(%{"type" => "Create", "object" => child_object} = object) do
scrub_policy = Pleroma.Config.get([:mrf_normalize_markup, :scrub_policy]) 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} def filter(object), do: {:ok, object}
@impl true
def describe, do: {:ok, %{}} 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 end

View File

@ -106,4 +106,32 @@ defmodule Pleroma.Web.ActivityPub.MRF.ObjectAgePolicy do
{:ok, %{mrf_object_age: mrf_object_age}} {:ok, %{mrf_object_age: mrf_object_age}}
end 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 end

View File

@ -48,4 +48,27 @@ defmodule Pleroma.Web.ActivityPub.MRF.RejectNonPublic do
@impl true @impl true
def describe, def describe,
do: {:ok, %{mrf_rejectnonpublic: Config.get(:mrf_rejectnonpublic) |> Enum.into(%{})}} 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 end

View File

@ -244,4 +244,78 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do
{:ok, %{mrf_simple: mrf_simple}} {:ok, %{mrf_simple: mrf_simple}}
end 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 end

View File

@ -39,4 +39,28 @@ defmodule Pleroma.Web.ActivityPub.MRF.SubchainPolicy do
@impl true @impl true
def describe, do: {:ok, %{}} 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 end

View File

@ -41,4 +41,25 @@ defmodule Pleroma.Web.ActivityPub.MRF.UserAllowListPolicy do
{:ok, %{mrf_user_allowlist: mrf_user_allowlist}} {:ok, %{mrf_user_allowlist: mrf_user_allowlist}}
end 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 end

View File

@ -7,6 +7,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.VocabularyPolicy do
@behaviour Pleroma.Web.ActivityPub.MRF @behaviour Pleroma.Web.ActivityPub.MRF
@impl true
def filter(%{"type" => "Undo", "object" => child_message} = message) do def filter(%{"type" => "Undo", "object" => child_message} = message) do
with {:ok, _} <- filter(child_message) do with {:ok, _} <- filter(child_message) do
{:ok, message} {:ok, message}
@ -36,6 +37,33 @@ defmodule Pleroma.Web.ActivityPub.MRF.VocabularyPolicy do
def filter(message), do: {:ok, message} def filter(message), do: {:ok, message}
@impl true
def describe, def describe,
do: {:ok, %{mrf_vocabulary: Pleroma.Config.get(:mrf_vocabulary) |> Enum.into(%{})}} 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 end

View File

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

View File

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

View File

@ -83,7 +83,7 @@ defmodule Pleroma.Web.Feed.FeedView do
def activity_content(_), 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 def attachment_href(attachment) do
attachment["url"] attachment["url"]

View File

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

View File

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

View File

@ -12,7 +12,7 @@
<link rel="ostatus:conversation"><%= activity_context(@activity) %></link> <link rel="ostatus:conversation"><%= activity_context(@activity) %></link>
<%= if @data["summary"] do %> <%= if @data["summary"] do %>
<description><%= @data["summary"] %></description> <description><%= escape(@data["summary"]) %></description>
<% end %> <% end %>
<%= if @activity.local do %> <%= 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 defmodule Mix.Tasks.Pleroma.InstanceTest do
use ExUnit.Case use ExUnit.Case
@release_env_file "./test/pleroma.test.env"
setup do setup do
File.mkdir_p!(tmp_path()) File.mkdir_p!(tmp_path())
@ -18,8 +16,6 @@ defmodule Mix.Tasks.Pleroma.InstanceTest do
File.rm_rf(Path.join(static_dir, "robots.txt")) File.rm_rf(Path.join(static_dir, "robots.txt"))
end end
if File.exists?(@release_env_file), do: File.rm_rf(@release_env_file)
Pleroma.Config.put([:instance, :static_dir], static_dir) Pleroma.Config.put([:instance, :static_dir], static_dir)
end) end)
@ -73,9 +69,7 @@ defmodule Mix.Tasks.Pleroma.InstanceTest do
"--dedupe-uploads", "--dedupe-uploads",
"n", "n",
"--anonymize-uploads", "--anonymize-uploads",
"n", "n"
"--release-env-file",
@release_env_file
]) ])
end end
@ -97,9 +91,6 @@ defmodule Mix.Tasks.Pleroma.InstanceTest do
assert generated_config =~ "filters: [Pleroma.Upload.Filter.ExifTool]" assert generated_config =~ "filters: [Pleroma.Upload.Filter.ExifTool]"
assert File.read!(tmp_path() <> "setup.psql") == generated_setup_psql() assert File.read!(tmp_path() <> "setup.psql") == generated_setup_psql()
assert File.exists?(Path.expand("./test/instance/static/robots.txt")) 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 end
defp generated_setup_psql do 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") AdminEmail.report(to_user, reporter, account, [%{name: "Test", id: "12"}], "Test comment")
status_url = Helpers.o_status_url(Pleroma.Web.Endpoint, :notice, "12") status_url = Helpers.o_status_url(Pleroma.Web.Endpoint, :notice, "12")
reporter_url = Helpers.user_feed_url(Pleroma.Web.Endpoint, :feed_redirect, reporter.id) reporter_url = reporter.ap_id
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.to == [{to_user.name, to_user.email}]
assert res.from == {config[:name], config[:notify_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) 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.to == [{to_user.name, to_user.email}]
assert res.from == {config[:name], config[:notify_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"} -> %{method: :get, url: "https://mastodon.example.org/users/userisgone404"} ->
%Tesla.Env{status: 404} %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 -> env ->
apply(HttpRequestMock, :request, [env]) apply(HttpRequestMock, :request, [env])
end) end)
@ -34,19 +45,22 @@ defmodule Pleroma.Object.FetcherTest do
%{method: :get, url: "https://social.sakamoto.gq/notice/9wTkLEnuq47B25EehM"} -> %{method: :get, url: "https://social.sakamoto.gq/notice/9wTkLEnuq47B25EehM"} ->
%Tesla.Env{ %Tesla.Env{
status: 200, 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"} -> %{method: :get, url: "https://social.sakamoto.gq/users/eal"} ->
%Tesla.Env{ %Tesla.Env{
status: 200, 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"} -> %{method: :get, url: "https://busshi.moe/users/tuxcrafting/statuses/104410921027210069"} ->
%Tesla.Env{ %Tesla.Env{
status: 200, 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"} -> %{method: :get, url: "https://busshi.moe/users/tuxcrafting"} ->
@ -132,6 +146,13 @@ defmodule Pleroma.Object.FetcherTest do
"http://mastodon.example.org/@admin/99541947525187367" "http://mastodon.example.org/@admin/99541947525187367"
) )
end 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 end
describe "implementation quirks" do describe "implementation quirks" do

View File

@ -281,7 +281,11 @@ defmodule Pleroma.ObjectTest do
setup do setup do
mock(fn mock(fn
%{method: :get, url: "https://patch.cx/objects/9a172665-2bc5-452d-8428-2361d4c33b1d"} -> %{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 -> env ->
apply(HttpRequestMock, :request, [env]) apply(HttpRequestMock, :request, [env])
@ -315,7 +319,8 @@ defmodule Pleroma.ObjectTest do
mock_modified.(%Tesla.Env{ mock_modified.(%Tesla.Env{
status: 200, 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) 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{ mock_modified.(%Tesla.Env{
status: 200, 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) 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{ mock_modified.(%Tesla.Env{
status: 200, 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) 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 -> mock(fn env ->
case env.url do case env.url do
"http://localhost:4001/users/masto_hidden_counters/following" -> "http://localhost:4001/users/masto_hidden_counters/following" ->
json(%{ json(
"@context" => "https://www.w3.org/ns/activitystreams", %{
"id" => "http://localhost:4001/users/masto_hidden_counters/followers" "@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" -> "http://localhost:4001/users/masto_hidden_counters/following?page=1" ->
%Tesla.Env{status: 403, body: ""} %Tesla.Env{status: 403, body: ""}
"http://localhost:4001/users/masto_hidden_counters/followers" -> "http://localhost:4001/users/masto_hidden_counters/followers" ->
json(%{ json(
"@context" => "https://www.w3.org/ns/activitystreams", %{
"id" => "http://localhost:4001/users/masto_hidden_counters/following" "@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" -> "http://localhost:4001/users/masto_hidden_counters/followers?page=1" ->
%Tesla.Env{status: 403, body: ""} %Tesla.Env{status: 403, body: ""}
@ -2278,7 +2284,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
Tesla.Mock.mock(fn Tesla.Mock.mock(fn
%{method: :get, url: "https://princess.cat/users/mewmew"} -> %{method: :get, url: "https://princess.cat/users/mewmew"} ->
file = File.read!("test/fixtures/mewmew_no_name.json") 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) end)
{:ok, user} = ActivityPub.make_user_from_ap_id("https://princess.cat/users/mewmew") {: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() {:ok, ^expected} = MRF.describe()
end end
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 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", "http://mastodon.example.org/system/media_attachments/files/000/000/002/original/334ce029e7bfb920.jpg",
"type" => "Document", "type" => "Document",
"name" => nil, "name" => nil,
"mediaType" => "image/jpeg" "mediaType" => "image/jpeg",
"blurhash" => "UD9jJz~VSbR#xT$~%KtQX9R,WAs9RjWBs:of"
} }
{:ok, attachment} = {:ok, attachment} =
@ -50,6 +51,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidatorTest do
] = attachment.url ] = attachment.url
assert attachment.mediaType == "image/jpeg" assert attachment.mediaType == "image/jpeg"
assert attachment.blurhash == "UD9jJz~VSbR#xT$~%KtQX9R,WAs9RjWBs:of"
end end
test "it handles our own uploads" do test "it handles our own uploads" do

View File

@ -60,7 +60,11 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.AnnounceHandlingTest do
Tesla.Mock.mock(fn Tesla.Mock.mock(fn
%{method: :get} -> %{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) end)
_user = insert(:user, local: false, ap_id: data["actor"]) _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 test "Pterotype (Wordpress Plugin) Article" do
Tesla.Mock.mock(fn %{url: "https://wedistribute.org/wp-json/pterotype/v1/actor/-blog"} -> 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) end)
data = data =
@ -36,13 +40,15 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.ArticleHandlingTest do
%{url: "https://baptiste.gelez.xyz/~/PlumeDevelopment/this-month-in-plume-june-2018/"} -> %{url: "https://baptiste.gelez.xyz/~/PlumeDevelopment/this-month-in-plume-june-2018/"} ->
%Tesla.Env{ %Tesla.Env{
status: 200, 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"} -> %{url: "https://baptiste.gelez.xyz/@/BaptisteGelez"} ->
%Tesla.Env{ %Tesla.Env{
status: 200, 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) end)
@ -61,7 +67,8 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.ArticleHandlingTest do
Tesla.Mock.mock(fn %{url: "https://prismo.news/@mxb"} -> Tesla.Mock.mock(fn %{url: "https://prismo.news/@mxb"} ->
%Tesla.Env{ %Tesla.Env{
status: 200, 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) end)

View File

@ -48,7 +48,8 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.AudioHandlingTest do
%{url: "https://channels.tests.funkwhale.audio/federation/actors/compositions"} -> %{url: "https://channels.tests.funkwhale.audio/federation/actors/compositions"} ->
%Tesla.Env{ %Tesla.Env{
status: 200, 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) end)
@ -69,6 +70,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.AudioHandlingTest do
"mediaType" => "audio/ogg", "mediaType" => "audio/ogg",
"type" => "Link", "type" => "Link",
"name" => nil, "name" => nil,
"blurhash" => nil,
"url" => [ "url" => [
%{ %{
"href" => "href" =>

View File

@ -13,13 +13,15 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.EventHandlingTest do
%{url: "https://mobilizon.org/events/252d5816-00a3-4a89-a66f-15bf65c33e39"} -> %{url: "https://mobilizon.org/events/252d5816-00a3-4a89-a66f-15bf65c33e39"} ->
%Tesla.Env{ %Tesla.Env{
status: 200, 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"} -> %{url: "https://mobilizon.org/@tcit"} ->
%Tesla.Env{ %Tesla.Env{
status: 200, 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) end)

View File

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

View File

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

View File

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

View File

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

View File

@ -5,6 +5,8 @@
defmodule HttpRequestMock do defmodule HttpRequestMock do
require Logger require Logger
def activitypub_object_headers, do: [{"content-type", "application/activity+json"}]
def request( def request(
%Tesla.Env{ %Tesla.Env{
url: url, url: url,
@ -34,7 +36,8 @@ defmodule HttpRequestMock do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, 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 end
@ -42,7 +45,8 @@ defmodule HttpRequestMock do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, 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 end
@ -50,7 +54,8 @@ defmodule HttpRequestMock do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, 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 end
@ -66,7 +71,8 @@ defmodule HttpRequestMock do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, 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 end
@ -78,7 +84,8 @@ defmodule HttpRequestMock do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, 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 end
@ -86,7 +93,8 @@ defmodule HttpRequestMock do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, 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 end
@ -99,7 +107,8 @@ defmodule HttpRequestMock do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, 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 end
@ -112,7 +121,8 @@ defmodule HttpRequestMock do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, 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 end
@ -190,7 +200,8 @@ defmodule HttpRequestMock do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, 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 end
@ -198,7 +209,8 @@ defmodule HttpRequestMock do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, 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 end
@ -211,7 +223,8 @@ defmodule HttpRequestMock do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, 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 end
@ -219,7 +232,8 @@ defmodule HttpRequestMock do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, 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 end
@ -227,7 +241,8 @@ defmodule HttpRequestMock do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, 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 end
@ -246,7 +261,8 @@ defmodule HttpRequestMock do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, 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 end
@ -254,7 +270,8 @@ defmodule HttpRequestMock do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, 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 end
@ -262,7 +279,8 @@ defmodule HttpRequestMock do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, 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 end
@ -270,7 +288,8 @@ defmodule HttpRequestMock do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, 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 end
@ -278,7 +297,8 @@ defmodule HttpRequestMock do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, 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 end
@ -286,7 +306,8 @@ defmodule HttpRequestMock do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, 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 end
@ -294,7 +315,8 @@ defmodule HttpRequestMock do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, 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 end
@ -304,7 +326,8 @@ defmodule HttpRequestMock do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, 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 end
@ -312,7 +335,8 @@ defmodule HttpRequestMock do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, 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 end
@ -320,7 +344,8 @@ defmodule HttpRequestMock do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, 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 end
@ -328,7 +353,8 @@ defmodule HttpRequestMock do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, 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 end
@ -336,7 +362,8 @@ defmodule HttpRequestMock do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, 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 end
@ -344,7 +371,8 @@ defmodule HttpRequestMock do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, 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 end
@ -352,7 +380,8 @@ defmodule HttpRequestMock do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, 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 end
@ -362,7 +391,8 @@ defmodule HttpRequestMock do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, 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 end
@ -482,7 +512,8 @@ defmodule HttpRequestMock do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, 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 end
@ -543,7 +574,8 @@ defmodule HttpRequestMock do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, 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 end
@ -567,7 +599,8 @@ defmodule HttpRequestMock do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, 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 end
@ -580,7 +613,8 @@ defmodule HttpRequestMock do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, 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 end
@ -795,7 +829,8 @@ defmodule HttpRequestMock do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, 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 end
@ -867,12 +902,21 @@ defmodule HttpRequestMock do
end end
def get("https://mastodon.social/users/lambadalambda", _, _, _) do 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 end
def get("https://apfed.club/channel/indio", _, _, _) do def get("https://apfed.club/channel/indio", _, _, _) do
{:ok, {: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 end
def get("https://social.heldscal.la/user/23211", _, _, [{"accept", "application/activity+json"}]) do def get("https://social.heldscal.la/user/23211", _, _, [{"accept", "application/activity+json"}]) do
@ -895,7 +939,8 @@ defmodule HttpRequestMock do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, 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 end
@ -903,7 +948,8 @@ defmodule HttpRequestMock do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, 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 end
@ -911,7 +957,8 @@ defmodule HttpRequestMock do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, 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 end
@ -919,7 +966,8 @@ defmodule HttpRequestMock do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, 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 end
@ -927,7 +975,8 @@ defmodule HttpRequestMock do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, 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 end
@ -935,7 +984,8 @@ defmodule HttpRequestMock do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, 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 end
@ -943,7 +993,8 @@ defmodule HttpRequestMock do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, 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 end
@ -951,7 +1002,8 @@ defmodule HttpRequestMock do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, 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 end
@ -1049,7 +1101,8 @@ defmodule HttpRequestMock do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, 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 end
@ -1063,7 +1116,8 @@ defmodule HttpRequestMock do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, 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 end
@ -1077,7 +1131,8 @@ defmodule HttpRequestMock do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, 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 end
@ -1110,7 +1165,12 @@ defmodule HttpRequestMock do
end end
def get("http://mastodon.example.org/@admin/99541947525187367", _, _, _) do 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 end
def get("https://info.pleroma.site/activity4.json", _, _, _) do def get("https://info.pleroma.site/activity4.json", _, _, _) do
@ -1137,7 +1197,8 @@ defmodule HttpRequestMock do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, 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 end
@ -1146,11 +1207,21 @@ defmodule HttpRequestMock do
end end
def get("https://skippers-bin.com/users/7v1w1r8ce6", _, _, _) do 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 end
def get("https://patch.cx/users/rin", _, _, _) do 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 end
def get( def get(
@ -1160,12 +1231,20 @@ defmodule HttpRequestMock do
_ _
) do ) do
{:ok, {: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 end
def get("https://channels.tests.funkwhale.audio/federation/actors/compositions", _, _, _) do def get("https://channels.tests.funkwhale.audio/federation/actors/compositions", _, _, _) do
{:ok, {: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 end
def get("http://example.com/rel_me/error", _, _, _) do def get("http://example.com/rel_me/error", _, _, _) do
@ -1173,7 +1252,12 @@ defmodule HttpRequestMock do
end end
def get("https://relay.mastodon.host/actor", _, _, _) do 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 end
def get("http://localhost:4001/", _, "", [{"accept", "text/html"}]) do def get("http://localhost:4001/", _, "", [{"accept", "text/html"}]) do