Merge remote-tracking branch 'origin/develop' into review-pr-7933
This commit is contained in:
commit
465a81ecf2
115 changed files with 1733 additions and 546 deletions
|
|
@ -1,85 +0,0 @@
|
|||
when:
|
||||
# Temporary PR validation while arm/v7 Docker builds are being brought up.
|
||||
- event: pull_request
|
||||
path: [ "**/*.ex", "**/*.eex", "**/*.exs", "mix.lock", ".woodpecker/**", "Dockerfile" ]
|
||||
- event: push
|
||||
branch: ${CI_REPO_DEFAULT_BRANCH}
|
||||
path: [ "**/*.ex", "**/*.eex", "**/*.exs", "mix.lock", ".woodpecker/**", "Dockerfile" ]
|
||||
- event: tag
|
||||
- event: manual
|
||||
branch: ${CI_REPO_DEFAULT_BRANCH}
|
||||
- event: manual
|
||||
branch: stable
|
||||
|
||||
# Target the CAX21 arm64 host with native arm32 userspace support, not generic arm64 runners.
|
||||
labels:
|
||||
platform: linux/arm
|
||||
armv7: native
|
||||
|
||||
variables:
|
||||
docker_variables: &docker_variables
|
||||
repo: pleroma/pleroma
|
||||
registry: git.pleroma.social
|
||||
armv7_build_settings: &armv7_build_settings
|
||||
<<: *docker_variables
|
||||
build_args:
|
||||
- ELIXIR_IMG=arm32v7/elixir
|
||||
- ELIXIR_TAG=1.17.3-otp-26-alpine
|
||||
- ALPINE_IMG=arm32v7/alpine
|
||||
- ALPINE_VER=3.20
|
||||
extra_opts: --custom-platform=linux/arm/v7
|
||||
armv7_push_settings: &armv7_push_settings
|
||||
<<: *armv7_build_settings
|
||||
username:
|
||||
from_secret: pleroma-ci-user
|
||||
password:
|
||||
from_secret: pleroma-ci-password
|
||||
|
||||
steps:
|
||||
docker-armv7-pr:
|
||||
image: woodpeckerci/plugin-kaniko:2.3.1
|
||||
when:
|
||||
- event: pull_request
|
||||
settings:
|
||||
<<: *armv7_build_settings
|
||||
dry_run: true
|
||||
tags:
|
||||
- armv7-pr-check
|
||||
|
||||
docker-develop-armv7:
|
||||
image: woodpeckerci/plugin-kaniko:2.3.1
|
||||
when:
|
||||
- event: push
|
||||
branch: ${CI_REPO_DEFAULT_BRANCH}
|
||||
- event: manual
|
||||
branch: ${CI_REPO_DEFAULT_BRANCH}
|
||||
settings:
|
||||
<<: *armv7_push_settings
|
||||
tags:
|
||||
- latest-armv7
|
||||
- develop-armv7
|
||||
- ${CI_COMMIT_SHA:0:8}-armv7
|
||||
|
||||
docker-stable-armv7:
|
||||
image: woodpeckerci/plugin-kaniko:2.3.1
|
||||
when:
|
||||
- evaluate: 'CI_PIPELINE_EVENT == "manual" && CI_COMMIT_BRANCH == "stable" && CI_COMMIT_TAG == ""'
|
||||
settings:
|
||||
<<: *armv7_push_settings
|
||||
tags:
|
||||
- latest-armv7
|
||||
- stable-armv7
|
||||
- ${CI_COMMIT_SHA:0:8}-armv7
|
||||
|
||||
docker-stable-tag-armv7:
|
||||
image: woodpeckerci/plugin-kaniko:2.3.1
|
||||
when:
|
||||
- event: tag
|
||||
- evaluate: 'CI_PIPELINE_EVENT == "manual" && CI_COMMIT_BRANCH == "stable" && CI_COMMIT_TAG != ""'
|
||||
settings:
|
||||
<<: *armv7_push_settings
|
||||
tags:
|
||||
- latest-armv7
|
||||
- stable-armv7
|
||||
- ${CI_COMMIT_SHA:0:8}-armv7
|
||||
- ${CI_COMMIT_TAG}-armv7
|
||||
|
|
@ -27,7 +27,7 @@ steps:
|
|||
settings: &docker_settings
|
||||
registry: "git.pleroma.social"
|
||||
image: "pleroma/pleroma"
|
||||
architectures: [amd64, arm64]
|
||||
architectures: [amd64, arm64, armv7]
|
||||
tags:
|
||||
- latest
|
||||
- develop
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ matrix:
|
|||
platform:
|
||||
- linux/amd64
|
||||
- linux/arm64
|
||||
- linux/arm
|
||||
|
||||
# This is needed for the when clauses below.
|
||||
labels:
|
||||
|
|
@ -26,11 +27,19 @@ variables:
|
|||
from_secret: pleroma-ci-user
|
||||
password:
|
||||
from_secret: pleroma-ci-password
|
||||
kaniko_image: &kaniko_image woodpeckerci/plugin-kaniko:2.3.1
|
||||
armv7_docker_variables: &armv7_docker_variables
|
||||
<<: *docker_variables
|
||||
build_args:
|
||||
- ELIXIR_IMG=docker.io/arm32v7/elixir
|
||||
- ELIXIR_TAG=1.17.3-otp-26-alpine
|
||||
- ALPINE_IMG=docker.io/arm32v7/alpine
|
||||
- ALPINE_VER=3.20
|
||||
extra_opts: --custom-platform=linux/arm/v7
|
||||
kaniko_image: &kaniko_image docker.io/woodpeckerci/plugin-kaniko:2.3.2
|
||||
|
||||
steps:
|
||||
docker-develop-amd64:
|
||||
image: woodpeckerci/plugin-kaniko:2.3.1
|
||||
image: *kaniko_image
|
||||
when:
|
||||
- evaluate: 'platform == "linux/amd64" && CI_COMMIT_BRANCH == "${CI_REPO_DEFAULT_BRANCH}"'
|
||||
settings:
|
||||
|
|
@ -41,7 +50,7 @@ steps:
|
|||
- ${CI_COMMIT_SHA:0:8}-amd64
|
||||
|
||||
docker-develop-arm64:
|
||||
image: woodpeckerci/plugin-kaniko:2.3.1
|
||||
image: *kaniko_image
|
||||
when:
|
||||
- evaluate: 'platform == "linux/arm64" && CI_COMMIT_BRANCH == "${CI_REPO_DEFAULT_BRANCH}"'
|
||||
settings:
|
||||
|
|
@ -51,6 +60,17 @@ steps:
|
|||
- develop-arm64
|
||||
- ${CI_COMMIT_SHA:0:8}-arm64
|
||||
|
||||
docker-develop-armv7:
|
||||
image: *kaniko_image
|
||||
when:
|
||||
- evaluate: 'platform == "linux/arm" && CI_COMMIT_BRANCH == "${CI_REPO_DEFAULT_BRANCH}"'
|
||||
settings:
|
||||
<<: *armv7_docker_variables
|
||||
tags:
|
||||
- latest-armv7
|
||||
- develop-armv7
|
||||
- ${CI_COMMIT_SHA:0:8}-armv7
|
||||
|
||||
docker-stable-amd64:
|
||||
image: *kaniko_image
|
||||
when:
|
||||
|
|
@ -106,3 +126,25 @@ steps:
|
|||
tags:
|
||||
- <<: *arm64_tags
|
||||
- ${CI_COMMIT_TAG}-arm64
|
||||
|
||||
docker-stable-armv7:
|
||||
image: *kaniko_image
|
||||
when:
|
||||
- evaluate: 'platform == "linux/arm" && CI_PIPELINE_EVENT == "manual" && CI_COMMIT_BRANCH == "stable" && CI_COMMIT_TAG == ""'
|
||||
settings:
|
||||
<<: *armv7_docker_variables
|
||||
tags: &armv7_tags
|
||||
- latest-armv7
|
||||
- stable-armv7
|
||||
- ${CI_COMMIT_SHA:0:8}-armv7
|
||||
|
||||
docker-stable-tag-armv7:
|
||||
image: *kaniko_image
|
||||
when:
|
||||
- evaluate: 'platform == "linux/arm" && CI_PIPELINE_EVENT == "tag"'
|
||||
- evaluate: 'platform == "linux/arm" && CI_PIPELINE_EVENT == "manual" && CI_COMMIT_BRANCH == "stable" && CI_COMMIT_TAG != ""'
|
||||
settings:
|
||||
<<: *armv7_docker_variables
|
||||
tags:
|
||||
- <<: *armv7_tags
|
||||
- ${CI_COMMIT_TAG}-armv7
|
||||
|
|
|
|||
|
|
@ -24,10 +24,11 @@ steps:
|
|||
entrypoint: *script_file_entrypoint
|
||||
environment:
|
||||
MIX_ENV: test
|
||||
VIX_COMPILATION_MODE: PLATFORM_PROVIDED_LIBVIPS
|
||||
DB_HOST: postgres
|
||||
DB_PORT: 5432
|
||||
commands:
|
||||
- apk add --no-cache build-base cmake exiftool ffmpeg file-dev git openssl
|
||||
- apk add --no-cache build-base cmake exiftool ffmpeg vips-dev file-dev git openssl
|
||||
- adduser -D -h /home/testuser testuser
|
||||
- mkdir -p /home/testuser/.mix /home/testuser/.hex
|
||||
- chown -R testuser:testuser . /home/testuser
|
||||
|
|
|
|||
|
|
@ -19,15 +19,16 @@ variables:
|
|||
- 'printf "%s" "$CI_SCRIPT" | base64 -d > /tmp/ci-script.sh && /bin/sh -xe /tmp/ci-script.sh'
|
||||
|
||||
steps:
|
||||
unit-testing-elixir-1.18:
|
||||
image: elixir:1.18-otp-27-alpine
|
||||
unit-testing-elixir-1.19:
|
||||
image: elixir:1.19-otp-28-alpine
|
||||
entrypoint: *script_file_entrypoint
|
||||
environment:
|
||||
MIX_ENV: test
|
||||
VIX_COMPILATION_MODE: PLATFORM_PROVIDED_LIBVIPS
|
||||
DB_HOST: postgres
|
||||
DB_PORT: 5432
|
||||
commands:
|
||||
- apk add --no-cache build-base cmake exiftool ffmpeg file-dev git openssl
|
||||
- apk add --no-cache build-base cmake exiftool ffmpeg vips-dev file-dev git openssl
|
||||
- adduser -D -h /home/testuser testuser
|
||||
- mkdir -p /home/testuser/.mix /home/testuser/.hex
|
||||
- chown -R testuser:testuser . /home/testuser
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
# https://hub.docker.com/r/hexpm/elixir/tags
|
||||
ARG ELIXIR_IMG=hexpm/elixir
|
||||
ARG ELIXIR_VER=1.17.3
|
||||
ARG ERLANG_VER=26.2.5.6
|
||||
ARG ALPINE_VER=3.17.9
|
||||
ARG ERLANG_VER=27.3.4.14
|
||||
ARG ALPINE_VER=3.23.5
|
||||
ARG ELIXIR_TAG=${ELIXIR_VER}-erlang-${ERLANG_VER}-alpine-${ALPINE_VER}
|
||||
ARG ALPINE_IMG=alpine
|
||||
|
||||
|
|
|
|||
1
changelog.d/disabling-chats.change
Normal file
1
changelog.d/disabling-chats.change
Normal file
|
|
@ -0,0 +1 @@
|
|||
Allow disabling Chats feature
|
||||
0
changelog.d/docker-arm32v7-pr-forbid-build.skip
Normal file
0
changelog.d/docker-arm32v7-pr-forbid-build.skip
Normal file
1
changelog.d/docker-baseimage-ssl.fix
Normal file
1
changelog.d/docker-baseimage-ssl.fix
Normal file
|
|
@ -0,0 +1 @@
|
|||
Dockerfile: update base images to fix problems with SSL handshakes
|
||||
1
changelog.d/elixir-1-19.add
Normal file
1
changelog.d/elixir-1-19.add
Normal file
|
|
@ -0,0 +1 @@
|
|||
Implemented ConfigDB configuration blacklist and accompanying Mix task
|
||||
1
changelog.d/elixir-1-19.fix
Normal file
1
changelog.d/elixir-1-19.fix
Normal file
|
|
@ -0,0 +1 @@
|
|||
Fixed Elixir 1.19 warnings
|
||||
1
changelog.d/fix-preferred-frontend.fix
Normal file
1
changelog.d/fix-preferred-frontend.fix
Normal file
|
|
@ -0,0 +1 @@
|
|||
Fix preferred frontend not working due to InstanceStatic plug prematurely returning HTTP 404
|
||||
1
changelog.d/hashtag-timeline.fix
Normal file
1
changelog.d/hashtag-timeline.fix
Normal file
|
|
@ -0,0 +1 @@
|
|||
Fix hashtag timeline query for additional tag handling
|
||||
1
changelog.d/logger-backends.change
Normal file
1
changelog.d/logger-backends.change
Normal file
|
|
@ -0,0 +1 @@
|
|||
Changed how Logger is configured due to changes in Elixir and added deprecation warnings for the old configuration format
|
||||
1
changelog.d/oauth-user-preload.change
Normal file
1
changelog.d/oauth-user-preload.change
Normal file
|
|
@ -0,0 +1 @@
|
|||
Avoid a duplicate user query during OAuth authentication.
|
||||
1
changelog.d/publisher-worker-atoms.fix
Normal file
1
changelog.d/publisher-worker-atoms.fix
Normal file
|
|
@ -0,0 +1 @@
|
|||
Avoid creating atoms from serialized PublisherWorker parameters.
|
||||
1
changelog.d/rss.fix
Normal file
1
changelog.d/rss.fix
Normal file
|
|
@ -0,0 +1 @@
|
|||
Fix RSS feeds to be W3C compliant and render better in RSS readers
|
||||
1
changelog.d/stream-domain-block-following.fix
Normal file
1
changelog.d/stream-domain-block-following.fix
Normal file
|
|
@ -0,0 +1 @@
|
|||
Keep followed users visible in streams when their domain is blocked.
|
||||
0
changelog.d/unit-testing-build-vix.skip
Normal file
0
changelog.d/unit-testing-build-vix.skip
Normal file
1
changelog.d/user-cache-keys.fix
Normal file
1
changelog.d/user-cache-keys.fix
Normal file
|
|
@ -0,0 +1 @@
|
|||
Fix inconsistent User cache keys and invalidate numeric ID aliases.
|
||||
1
changelog.d/woodpecker-armv7-fixups.fix
Normal file
1
changelog.d/woodpecker-armv7-fixups.fix
Normal file
|
|
@ -0,0 +1 @@
|
|||
Include arm32v7 in multi-arch Docker images
|
||||
|
|
@ -133,13 +133,17 @@ config :pleroma, Pleroma.Web.Endpoint,
|
|||
]
|
||||
|
||||
# Configures Elixir's Logger
|
||||
config :logger, backends: [:console]
|
||||
# Primary config
|
||||
config :logger, level: :debug
|
||||
|
||||
config :logger, :console,
|
||||
level: :debug,
|
||||
# Console config
|
||||
config :logger, :default_handler, level: :debug
|
||||
|
||||
config :logger, :default_formatter,
|
||||
format: "\n$time $metadata[$level] $message\n",
|
||||
metadata: [:actor, :path, :type, :user]
|
||||
|
||||
# Syslog config
|
||||
config :logger, :ex_syslogger,
|
||||
level: :debug,
|
||||
ident: "pleroma",
|
||||
|
|
@ -962,6 +966,10 @@ config :pleroma, Pleroma.Search.QdrantSearch,
|
|||
vectors: %{size: 384, distance: "Cosine"}
|
||||
}
|
||||
|
||||
config :pleroma, :database_config_blacklist, [
|
||||
{:pleroma, :logger}
|
||||
]
|
||||
|
||||
config :pleroma, :database_config_whitelist, [
|
||||
{:pleroma},
|
||||
{:cors_plug},
|
||||
|
|
@ -971,6 +979,8 @@ config :pleroma, :database_config_whitelist, [
|
|||
{:web_push_encryption, :vapid_details}
|
||||
]
|
||||
|
||||
config :pleroma, Pleroma.Chat, enabled: true
|
||||
|
||||
# Import environment specific config. This must remain at the bottom
|
||||
# of this file so it overrides the configuration defined above.
|
||||
import_config "#{Mix.env()}.exs"
|
||||
|
|
|
|||
|
|
@ -2726,6 +2726,19 @@ config :pleroma, :config_description, [
|
|||
}
|
||||
]
|
||||
},
|
||||
%{
|
||||
group: :pleroma,
|
||||
key: Pleroma.Chat,
|
||||
type: :group,
|
||||
description: "Pleroma Chat settings",
|
||||
children: [
|
||||
%{
|
||||
key: :enabled,
|
||||
type: :boolean,
|
||||
description: "Enables the chats API."
|
||||
}
|
||||
]
|
||||
},
|
||||
%{
|
||||
group: :pleroma,
|
||||
key: :http,
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ config :pleroma, Pleroma.Emails.Mailer, adapter: Swoosh.Adapters.Local
|
|||
# different ports.
|
||||
|
||||
# Do not include timestamps in development logs
|
||||
config :logger, Logger.Backends.Console, format: "$metadata[$level] $message\n"
|
||||
config :logger, :default_formatter, format: "$metadata[$level] $message\n"
|
||||
|
||||
# Set a higher stacktrace during development. Avoid configuring such
|
||||
# in production as building large stacktraces may be expensive.
|
||||
|
|
|
|||
|
|
@ -20,8 +20,7 @@ config :pleroma, Pleroma.Web.Endpoint,
|
|||
config :phoenix, serve_endpoints: true
|
||||
|
||||
# Do not print debug messages in production
|
||||
config :logger, Logger.Backends.Console, level: :info
|
||||
config :logger, :console, level: :info
|
||||
config :logger, :default_handler, level: :info
|
||||
config :logger, :ex_syslogger, level: :info
|
||||
|
||||
# ## SSL Support
|
||||
|
|
|
|||
|
|
@ -15,9 +15,11 @@ config :pleroma, Pleroma.Captcha,
|
|||
method: Pleroma.Captcha.Mock
|
||||
|
||||
# Print only warnings and errors during test
|
||||
config :logger, :console,
|
||||
level: :warning,
|
||||
format: "\n[$level] $message\n"
|
||||
config :logger, :default_handler, level: :warning
|
||||
|
||||
config :logger, :default_formatter,
|
||||
format: "\n[$level] $message\n",
|
||||
colors: [enabled: false]
|
||||
|
||||
config :pleroma, :auth, oauth_consumer_strategies: []
|
||||
|
||||
|
|
|
|||
|
|
@ -858,21 +858,23 @@ Web Push Notifications configuration. You can use the mix task `mix web_push.gen
|
|||
* ``private_key``: VAPID private key
|
||||
|
||||
## :logger
|
||||
* `backends`: `:console` is used to send logs to stdout, `{ExSyslogger, :ex_syslogger}` to log to syslog
|
||||
* Logging to console/stdout is done by default, use `{ExSyslogger, :ex_syslogger}` to log to syslog
|
||||
|
||||
An example to enable ONLY ExSyslogger (f/ex in ``prod.secret.exs``) with info and debug suppressed:
|
||||
```elixir
|
||||
config :logger,
|
||||
config :pleroma, :logger,
|
||||
backends: [{ExSyslogger, :ex_syslogger}]
|
||||
|
||||
config :logger, default_handler: false
|
||||
|
||||
config :logger, :ex_syslogger,
|
||||
level: :warning
|
||||
```
|
||||
|
||||
Another example, keeping console output and adding the pid to syslog output:
|
||||
```elixir
|
||||
config :logger,
|
||||
backends: [:console, {ExSyslogger, :ex_syslogger}]
|
||||
config :pleroma, :logger,
|
||||
backends: [{ExSyslogger, :ex_syslogger}]
|
||||
|
||||
config :logger, :ex_syslogger,
|
||||
level: :warning,
|
||||
|
|
@ -883,23 +885,22 @@ See: [logger’s documentation](https://hexdocs.pm/logger/Logger.html) and [ex_s
|
|||
|
||||
An example of logging info to local syslog, but debug to console:
|
||||
```elixir
|
||||
config :logger,
|
||||
backends: [ {ExSyslogger, :ex_syslogger}, :console ],
|
||||
level: :info
|
||||
config :pleroma, :logger,
|
||||
backends: [{ExSyslogger, :ex_syslogger}]
|
||||
|
||||
config :logger, :ex_syslogger,
|
||||
level: :info,
|
||||
ident: "pleroma",
|
||||
format: "$metadata[$level] $message"
|
||||
|
||||
config :logger, :console,
|
||||
level: :debug,
|
||||
config :logger, :default_handler,
|
||||
level: :debug
|
||||
|
||||
config :logger, :default_formatter,
|
||||
format: "\n$time $metadata[$level] $message\n",
|
||||
metadata: [:request_id]
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Database options
|
||||
|
||||
### RUM indexing for full text search
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
## Required dependencies
|
||||
|
||||
* PostgreSQL >=11.0
|
||||
* Elixir >=1.15.0 <1.19
|
||||
* Erlang OTP >=23.0.0 (supported: <28)
|
||||
* Elixir >=1.15.0, <1.20
|
||||
* Erlang OTP >=24.0.0 (supported: <29)
|
||||
* git
|
||||
* file / libmagic
|
||||
* gcc or clang
|
||||
|
|
|
|||
|
|
@ -252,40 +252,43 @@ defmodule Mix.Tasks.Pleroma.Config do
|
|||
if whitelisted_configs in [nil, false] do
|
||||
shell_error("No unwanted settings in ConfigDB. No changes made.")
|
||||
else
|
||||
whitelisted_groups =
|
||||
whitelisted_configs
|
||||
|> Enum.filter(fn
|
||||
{_group} -> true
|
||||
_ -> false
|
||||
end)
|
||||
|> Enum.map(fn {group} -> group end)
|
||||
|
||||
whitelisted_keys =
|
||||
whitelisted_configs
|
||||
|> Enum.filter(fn
|
||||
{_group, _key} -> true
|
||||
_ -> false
|
||||
end)
|
||||
{whitelisted_groups, whitelisted_keys} = get_filters(whitelisted_configs)
|
||||
|
||||
filtered =
|
||||
from(c in ConfigDB)
|
||||
|> Repo.all()
|
||||
|> Enum.filter(¬_whitelisted?(&1, whitelisted_groups, whitelisted_keys))
|
||||
|
||||
if not Enum.empty?(filtered) do
|
||||
shell_info("The following settings will be removed from ConfigDB:\n")
|
||||
Enum.each(filtered, &dump(&1))
|
||||
do_config_filter(filtered, force)
|
||||
end
|
||||
end
|
||||
|
||||
if force or shell_prompt("Are you sure you want to continue?", "n") in ~w(Yn Y y) do
|
||||
filtered_ids = Enum.map(filtered, fn %{id: id} -> id end)
|
||||
# Removes blacklisted configuration sections
|
||||
def run(["filter_blacklisted" | rest]) do
|
||||
{options, [], []} =
|
||||
OptionParser.parse(
|
||||
rest,
|
||||
strict: [force: :boolean],
|
||||
aliases: [f: :force]
|
||||
)
|
||||
|
||||
Repo.delete_all(from(c in ConfigDB, where: c.id in ^filtered_ids))
|
||||
else
|
||||
shell_error("No changes made.")
|
||||
end
|
||||
else
|
||||
shell_error("No unwanted settings in ConfigDB. No changes made.")
|
||||
end
|
||||
force = Keyword.get(options, :force, false)
|
||||
|
||||
start_pleroma()
|
||||
|
||||
blacklisted_configs = Pleroma.Config.get(:database_config_blacklist)
|
||||
|
||||
if blacklisted_configs in [nil, false] do
|
||||
shell_error("No unwanted settings in ConfigDB. No changes made.")
|
||||
else
|
||||
{blacklisted_groups, blacklisted_keys} = get_filters(blacklisted_configs)
|
||||
|
||||
filtered =
|
||||
from(c in ConfigDB)
|
||||
|> Repo.all()
|
||||
|> Enum.filter(&blacklisted?(&1, blacklisted_groups, blacklisted_keys))
|
||||
|
||||
do_config_filter(filtered, force)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -490,8 +493,49 @@ defmodule Mix.Tasks.Pleroma.Config do
|
|||
Ecto.Adapters.SQL.query!(Repo, "ALTER SEQUENCE config_id_seq RESTART;")
|
||||
end
|
||||
|
||||
defp get_filters(config) do
|
||||
groups =
|
||||
config
|
||||
|> Enum.filter(fn
|
||||
{_group} -> true
|
||||
_ -> false
|
||||
end)
|
||||
|> Enum.map(fn {group} -> group end)
|
||||
|
||||
keys =
|
||||
config
|
||||
|> Enum.filter(fn
|
||||
{_group, _key} -> true
|
||||
_ -> false
|
||||
end)
|
||||
|
||||
{groups, keys}
|
||||
end
|
||||
|
||||
defp not_whitelisted?(%{group: group, key: key}, whitelisted_groups, whitelisted_keys) do
|
||||
not Enum.member?(whitelisted_groups, group) and
|
||||
not Enum.member?(whitelisted_keys, {group, key})
|
||||
end
|
||||
|
||||
defp blacklisted?(%{group: group, key: key}, blacklisted_groups, blacklisted_keys) do
|
||||
Enum.member?(blacklisted_groups, group) or
|
||||
Enum.member?(blacklisted_keys, {group, key})
|
||||
end
|
||||
|
||||
defp do_config_filter(filtered, _) when length(filtered) == 0 do
|
||||
shell_error("No unwanted settings in ConfigDB. No changes made.")
|
||||
end
|
||||
|
||||
defp do_config_filter(filtered, force) do
|
||||
shell_info("The following settings will be removed from ConfigDB:\n")
|
||||
Enum.each(filtered, &dump(&1))
|
||||
|
||||
if force or shell_prompt("Are you sure you want to continue?", "n") in ~w(Yn Y y) do
|
||||
filtered_ids = Enum.map(filtered, fn %{id: id} -> id end)
|
||||
|
||||
Repo.delete_all(from(c in ConfigDB, where: c.id in ^filtered_ids))
|
||||
else
|
||||
shell_error("No changes made.")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ defmodule Pleroma.Application do
|
|||
# every time the application is restarted, so we disable module
|
||||
# conflicts at runtime
|
||||
Code.compiler_options(ignore_module_conflict: true)
|
||||
configure_logger()
|
||||
Pleroma.Telemetry.Logger.attach()
|
||||
Config.Holder.save_default()
|
||||
Pleroma.HTML.compile_scrubbers()
|
||||
|
|
@ -113,6 +114,44 @@ defmodule Pleroma.Application do
|
|||
Supervisor.start_link(children, opts)
|
||||
end
|
||||
|
||||
def configure_logger do
|
||||
Config.get([:logger, :backends], [])
|
||||
|> Enum.each(fn backend ->
|
||||
case backend_to_logger(backend) do
|
||||
{:ok, logger} ->
|
||||
add_logger(logger)
|
||||
|
||||
{:error, :console_backend} ->
|
||||
Logger.warning(":console is no longer considered a backend and is enabled by default")
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
defp add_logger(backend) do
|
||||
case LoggerBackends.add(backend) do
|
||||
{:ok, _} ->
|
||||
Logger.debug("Successfully added logger backend: #{inspect(backend)}")
|
||||
|
||||
{:error, :already_present} ->
|
||||
:ok
|
||||
|
||||
{:error, reason} ->
|
||||
Logger.error("Failed to add logger backend #{inspect(backend)}: #{inspect(reason)}")
|
||||
end
|
||||
end
|
||||
|
||||
defp backend_to_logger(:console), do: {:error, :console_backend}
|
||||
|
||||
defp backend_to_logger({:ex_syslogger = backend, name}) do
|
||||
Logger.warning(
|
||||
"Configuration {:#{backend}, :#{name}} is incorrect. Use {ExSyslogger, :#{name}} instead!"
|
||||
)
|
||||
|
||||
{:ok, {ExSyslogger, name}}
|
||||
end
|
||||
|
||||
defp backend_to_logger(backend), do: {:ok, backend}
|
||||
|
||||
def load_custom_modules do
|
||||
dir = Config.get([:modules, :runtime_dir])
|
||||
|
||||
|
|
|
|||
|
|
@ -108,4 +108,6 @@ defmodule Pleroma.Chat do
|
|||
|> cast(%{pinned: false}, [:pinned])
|
||||
|> Repo.update()
|
||||
end
|
||||
|
||||
def enabled?, do: Pleroma.Config.get([__MODULE__, :enabled], true)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ defmodule Pleroma.Config.DeprecationWarnings do
|
|||
"\n* `config :pleroma, :instance, mrf_transparency_exclusions` is now `config :pleroma, :mrf, transparency_exclusions`"}
|
||||
]
|
||||
|
||||
@logger_formatter_config_knobs [:colors, :format, :metadata, :truncate, :utc_log]
|
||||
|
||||
def check_exiftool_filter do
|
||||
filters = Config.get([Pleroma.Upload]) |> Keyword.get(:filters, [])
|
||||
|
||||
|
|
@ -218,7 +220,8 @@ defmodule Pleroma.Config.DeprecationWarnings do
|
|||
check_quarantined_instances_tuples(),
|
||||
check_transparency_exclusions_tuples(),
|
||||
check_simple_policy_tuples(),
|
||||
check_exiftool_filter()
|
||||
check_exiftool_filter(),
|
||||
check_deprecated_logger_config()
|
||||
]
|
||||
|> Enum.reduce(:ok, fn
|
||||
:ok, :ok -> :ok
|
||||
|
|
@ -415,4 +418,72 @@ defmodule Pleroma.Config.DeprecationWarnings do
|
|||
:ok
|
||||
end
|
||||
end
|
||||
|
||||
defp merge_deprecated_logger_config(config) do
|
||||
formatter_config = Enum.filter(config, fn {k, _} -> k in @logger_formatter_config_knobs end)
|
||||
formatter = Logger.default_formatter(formatter_config)
|
||||
log_level = Keyword.get(config, :level, nil)
|
||||
|
||||
Logger.debug("""
|
||||
Reconfiguring console Logger with deprecated configuration syntax.
|
||||
Handler configuration:
|
||||
log_level: #{inspect(log_level)}
|
||||
|
||||
Formatter:
|
||||
#{inspect(formatter)}
|
||||
""")
|
||||
|
||||
if Config.get(:env) != :test do
|
||||
if log_level, do: :logger.update_handler_config(:default, :level, log_level)
|
||||
:logger.set_handler_config(:default, :formatter, formatter)
|
||||
end
|
||||
end
|
||||
|
||||
@spec check_deprecated_logger_config() :: :ok | :error
|
||||
def check_deprecated_logger_config do
|
||||
backends_config = Application.get_env(:logger, :backends)
|
||||
console_config = Application.get_env(:logger, :console)
|
||||
|
||||
# NOTE: No need to merge the old backends config since it still works.
|
||||
# And new configuration will just add new Logger backends.
|
||||
backend =
|
||||
if backends_config do
|
||||
Logger.warning("""
|
||||
!!!DEPRECATION WARNING!!!
|
||||
Your configuration is using deprecated syntax for configuring backends of Elixir's logger.
|
||||
`config :logger, backends: [...]` is deprecated syntax due to changes in Elixir.
|
||||
Please update your configuration at your earliest convenience to use:
|
||||
`config :pleroma, :logger, backends: [...]`
|
||||
|
||||
Note: `:console` is no longer considered a backend and is used by default, you can disable it using:
|
||||
`config :logger, :default_handler: false`
|
||||
""")
|
||||
|
||||
true
|
||||
else
|
||||
false
|
||||
end
|
||||
|
||||
console =
|
||||
if console_config do
|
||||
Logger.warning("""
|
||||
!!!DEPRECATION WARNING!!!
|
||||
Your configuration is using deprecated syntax for configuring logging to console.
|
||||
`config :logger, :console` is deprecated syntax due to changes in Elixir.
|
||||
Please update your configuration at your earliest convenience to use
|
||||
`config :logger, default_handler` and `config :logger, :default_formatter`.
|
||||
|
||||
Note: `:default_handler` is used only for the `level` setting. All other configurations go under
|
||||
`:default_formatter`. For more info visit: https://hexdocs.pm/logger/Logger.html#module-backends-and-backwards-compatibility
|
||||
""")
|
||||
|
||||
merge_deprecated_logger_config(console_config)
|
||||
|
||||
true
|
||||
else
|
||||
false
|
||||
end
|
||||
|
||||
if backend or console, do: :error, else: :ok
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ defmodule Pleroma.Config.TransferTask do
|
|||
|
||||
started_applications = Application.started_applications()
|
||||
|
||||
reject = [nil, :postgrex]
|
||||
reject = [nil, :postgrex, :logger]
|
||||
|
||||
reject =
|
||||
if restart_pleroma? do
|
||||
|
|
|
|||
|
|
@ -12,13 +12,27 @@ defmodule Pleroma.Docs.Generator do
|
|||
|
||||
@spec list_behaviour_implementations(behaviour :: module()) :: [module()]
|
||||
def list_behaviour_implementations(behaviour) do
|
||||
:code.all_loaded()
|
||||
|> Enum.filter(fn {module, _} ->
|
||||
# :code.all_loaded() no longer works on Elixir 1.19 and newer since modules are lazily loaded.
|
||||
# We can get a complete list of modules by interating over Application.loaded_applications/0,
|
||||
# but that includes every module which would get loaded below, which is very slow.
|
||||
# Hardcode the Pleroma application instead, which is good enough for now.
|
||||
application_modules =
|
||||
case :application.get_key(:pleroma, :modules) do
|
||||
{:ok, modules} -> modules
|
||||
:undefined -> []
|
||||
end
|
||||
|
||||
# At compile time or in tests some modules will be outside of the Pleroma application.
|
||||
loaded_modules = Enum.map(:code.all_loaded(), fn {module, _} -> module end)
|
||||
|
||||
(application_modules ++ loaded_modules)
|
||||
|> Enum.uniq()
|
||||
|> Enum.filter(fn module ->
|
||||
Code.ensure_loaded(module)
|
||||
|
||||
# This shouldn't be needed as all modules are expected to have module_info/1,
|
||||
# but in test environments some transient modules `:elixir_compiler_XX`
|
||||
# are loaded for some reason (where XX is a random integer).
|
||||
Code.ensure_loaded(module)
|
||||
|
||||
if function_exported?(module, :module_info, 1) do
|
||||
module.module_info(:attributes)
|
||||
|> Keyword.get_values(:behaviour)
|
||||
|
|
@ -26,7 +40,6 @@ defmodule Pleroma.Docs.Generator do
|
|||
|> Enum.member?(behaviour)
|
||||
end
|
||||
end)
|
||||
|> Enum.map(fn {module, _} -> module end)
|
||||
end
|
||||
|
||||
@doc """
|
||||
|
|
|
|||
|
|
@ -272,13 +272,13 @@ defmodule Pleroma.User do
|
|||
end
|
||||
|
||||
def cached_blocked_users_ap_ids(user) do
|
||||
@cachex.fetch!(:user_cache, "blocked_users_ap_ids:#{user.ap_id}", fn _ ->
|
||||
@cachex.fetch!(:user_cache, cache_key(:blocked_users_ap_ids, user), fn _ ->
|
||||
blocked_users_ap_ids(user)
|
||||
end)
|
||||
end
|
||||
|
||||
def cached_muted_users_ap_ids(user) do
|
||||
@cachex.fetch!(:user_cache, "muted_users_ap_ids:#{user.ap_id}", fn _ ->
|
||||
@cachex.fetch!(:user_cache, cache_key(:muted_users_ap_ids, user), fn _ ->
|
||||
muted_users_ap_ids(user)
|
||||
end)
|
||||
end
|
||||
|
|
@ -1253,13 +1253,18 @@ defmodule Pleroma.User do
|
|||
get_cached_by_nickname(nickname)
|
||||
end
|
||||
|
||||
defp cache_key(:id, %User{id: id}), do: cache_key(:id, id)
|
||||
defp cache_key(:nickname, %User{nickname: nickname}), do: cache_key(:nickname, nickname)
|
||||
defp cache_key(namespace, %User{ap_id: ap_id}), do: cache_key(namespace, ap_id)
|
||||
defp cache_key(namespace, value), do: "#{namespace}:#{value}"
|
||||
|
||||
def set_cache({:ok, user}), do: set_cache(user)
|
||||
def set_cache({:error, err}), do: {:error, err}
|
||||
|
||||
def set_cache(%User{} = user) do
|
||||
@cachex.put(:user_cache, "ap_id:#{user.ap_id}", user)
|
||||
@cachex.put(:user_cache, "nickname:#{user.nickname}", user)
|
||||
@cachex.put(:user_cache, "friends_ap_ids:#{user.nickname}", get_user_friends_ap_ids(user))
|
||||
@cachex.put(:user_cache, cache_key(:ap_id, user), user)
|
||||
@cachex.put(:user_cache, cache_key(:nickname, user), user)
|
||||
@cachex.put(:user_cache, cache_key(:friends_ap_ids, user), get_user_friends_ap_ids(user))
|
||||
{:ok, user}
|
||||
end
|
||||
|
||||
|
|
@ -1287,22 +1292,23 @@ defmodule Pleroma.User do
|
|||
|
||||
@spec get_cached_user_friends_ap_ids(User.t()) :: [String.t()]
|
||||
def get_cached_user_friends_ap_ids(user) do
|
||||
@cachex.fetch!(:user_cache, "friends_ap_ids:#{user.ap_id}", fn _ ->
|
||||
@cachex.fetch!(:user_cache, cache_key(:friends_ap_ids, user), fn _ ->
|
||||
get_user_friends_ap_ids(user)
|
||||
end)
|
||||
end
|
||||
|
||||
def invalidate_cache(user) do
|
||||
@cachex.del(:user_cache, "ap_id:#{user.ap_id}")
|
||||
@cachex.del(:user_cache, "nickname:#{user.nickname}")
|
||||
@cachex.del(:user_cache, "friends_ap_ids:#{user.ap_id}")
|
||||
@cachex.del(:user_cache, "blocked_users_ap_ids:#{user.ap_id}")
|
||||
@cachex.del(:user_cache, "muted_users_ap_ids:#{user.ap_id}")
|
||||
@cachex.del(:user_cache, cache_key(:ap_id, user))
|
||||
@cachex.del(:user_cache, cache_key(:nickname, user))
|
||||
@cachex.del(:user_cache, cache_key(:id, user))
|
||||
@cachex.del(:user_cache, cache_key(:friends_ap_ids, user))
|
||||
@cachex.del(:user_cache, cache_key(:blocked_users_ap_ids, user))
|
||||
@cachex.del(:user_cache, cache_key(:muted_users_ap_ids, user))
|
||||
end
|
||||
|
||||
@spec get_cached_by_ap_id(String.t()) :: User.t() | nil
|
||||
def get_cached_by_ap_id(ap_id) do
|
||||
key = "ap_id:#{ap_id}"
|
||||
key = cache_key(:ap_id, ap_id)
|
||||
|
||||
with {:ok, nil} <- @cachex.get(:user_cache, key),
|
||||
user when not is_nil(user) <- get_by_ap_id(ap_id),
|
||||
|
|
@ -1315,14 +1321,14 @@ defmodule Pleroma.User do
|
|||
end
|
||||
|
||||
def get_cached_by_id(id) do
|
||||
key = "id:#{id}"
|
||||
key = cache_key(:id, id)
|
||||
|
||||
ap_id =
|
||||
@cachex.fetch!(:user_cache, key, fn _ ->
|
||||
user = get_by_id(id)
|
||||
|
||||
if user do
|
||||
@cachex.put(:user_cache, "ap_id:#{user.ap_id}", user)
|
||||
@cachex.put(:user_cache, cache_key(:ap_id, user), user)
|
||||
{:commit, user.ap_id}
|
||||
else
|
||||
{:ignore, ""}
|
||||
|
|
@ -1333,7 +1339,7 @@ defmodule Pleroma.User do
|
|||
end
|
||||
|
||||
def get_cached_by_nickname(nickname) do
|
||||
key = "nickname:#{nickname}"
|
||||
key = cache_key(:nickname, nickname)
|
||||
|
||||
@cachex.fetch!(:user_cache, key, fn _ ->
|
||||
case get_or_fetch_by_nickname(nickname) do
|
||||
|
|
@ -1651,7 +1657,7 @@ defmodule Pleroma.User do
|
|||
|> Oban.insert()
|
||||
end
|
||||
|
||||
@cachex.del(:user_cache, "muted_users_ap_ids:#{muter.ap_id}")
|
||||
@cachex.del(:user_cache, cache_key(:muted_users_ap_ids, muter))
|
||||
|
||||
{:ok, Enum.filter([user_mute, user_notification_mute], & &1)}
|
||||
end
|
||||
|
|
@ -1661,7 +1667,7 @@ defmodule Pleroma.User do
|
|||
with {:ok, user_mute} <- UserRelationship.delete_mute(muter, mutee),
|
||||
{:ok, user_notification_mute} <-
|
||||
UserRelationship.delete_notification_mute(muter, mutee) do
|
||||
@cachex.del(:user_cache, "muted_users_ap_ids:#{muter.ap_id}")
|
||||
@cachex.del(:user_cache, cache_key(:muted_users_ap_ids, muter))
|
||||
{:ok, [user_mute, user_notification_mute]}
|
||||
end
|
||||
end
|
||||
|
|
@ -2815,7 +2821,7 @@ defmodule Pleroma.User do
|
|||
{:ok, UserRelationship.t()} | {:error, Ecto.Changeset.t()}
|
||||
defp add_to_block(%User{} = user, %User{} = blocked, expires_at) do
|
||||
with {:ok, relationship} <- UserRelationship.create_block(user, blocked, expires_at) do
|
||||
@cachex.del(:user_cache, "blocked_users_ap_ids:#{user.ap_id}")
|
||||
@cachex.del(:user_cache, cache_key(:blocked_users_ap_ids, user))
|
||||
{:ok, relationship}
|
||||
end
|
||||
end
|
||||
|
|
@ -2824,7 +2830,7 @@ defmodule Pleroma.User do
|
|||
{:ok, UserRelationship.t()} | {:ok, nil} | {:error, Ecto.Changeset.t()}
|
||||
defp remove_from_block(%User{} = user, %User{} = blocked) do
|
||||
with {:ok, relationship} <- UserRelationship.delete_block(user, blocked) do
|
||||
@cachex.del(:user_cache, "blocked_users_ap_ids:#{user.ap_id}")
|
||||
@cachex.del(:user_cache, cache_key(:blocked_users_ap_ids, user))
|
||||
{:ok, relationship}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -893,14 +893,22 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|
|||
|> Repo.all()
|
||||
|
||||
# Note: NO extra ordering should be done on "activities.id desc nulls last" for optimal plan
|
||||
from(
|
||||
[_activity, object] in query,
|
||||
join: hto in "hashtags_objects",
|
||||
on: hto.object_id == object.id,
|
||||
where: hto.hashtag_id in ^hashtag_ids,
|
||||
distinct: [desc: object.id],
|
||||
order_by: [desc: object.id]
|
||||
)
|
||||
query =
|
||||
from(
|
||||
[_activity, object] in query,
|
||||
join: hto in "hashtags_objects",
|
||||
on: hto.object_id == object.id,
|
||||
where: hto.hashtag_id in ^hashtag_ids
|
||||
)
|
||||
|
||||
if is_nil(query.distinct) do
|
||||
from([_activity, object] in query,
|
||||
distinct: [desc: object.id],
|
||||
order_by: [desc: object.id]
|
||||
)
|
||||
else
|
||||
query
|
||||
end
|
||||
end
|
||||
|
||||
defp restrict_hashtag_any(query, %{tag: tag}) when is_binary(tag) do
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.ActivityExpirationPolicy do
|
|||
@moduledoc "Adds expiration to all local Create activities"
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
use Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
@impl true
|
||||
def filter(activity) do
|
||||
activity =
|
||||
|
|
|
|||
|
|
@ -3,11 +3,11 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.MRF.AntiFollowbotPolicy do
|
||||
@moduledoc "Prevent followbots from following with a bit of heuristic"
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
alias Pleroma.User
|
||||
|
||||
@moduledoc "Prevent followbots from following with a bit of heuristic"
|
||||
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
use Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
# XXX: this should become User.normalize_by_ap_id() or similar, really.
|
||||
defp normalize_by_ap_id(%{"id" => id}), do: User.get_cached_by_ap_id(id)
|
||||
|
|
|
|||
|
|
@ -3,9 +3,11 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.MRF.AntiLinkSpamPolicy do
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
alias Pleroma.User
|
||||
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
use Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
require Logger
|
||||
|
||||
|
|
|
|||
|
|
@ -3,11 +3,13 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.MRF.AntiMentionSpamPolicy do
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
alias Pleroma.Config
|
||||
alias Pleroma.User
|
||||
require Pleroma.Constants
|
||||
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
use Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
defp user_has_posted?(%User{} = u), do: u.note_count > 0
|
||||
|
||||
|
|
|
|||
|
|
@ -3,10 +3,12 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.MRF.DropPolicy do
|
||||
require Logger
|
||||
@moduledoc "Drop and log everything received"
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
require Logger
|
||||
use Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
@impl true
|
||||
def filter(activity) do
|
||||
Logger.debug("REJECTING #{inspect(activity)}")
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.MRF.EmojiPolicy do
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
require Pleroma.Constants
|
||||
|
||||
alias Pleroma.Object.Updater
|
||||
|
|
@ -10,7 +12,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.EmojiPolicy do
|
|||
|
||||
@moduledoc "Reject or force-unlisted emojis with certain URLs or names"
|
||||
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
use Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
defp config_remove_url do
|
||||
Pleroma.Config.get([:mrf_emoji, :remove_url], [])
|
||||
|
|
|
|||
|
|
@ -3,11 +3,13 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.MRF.EnsureRePrepended do
|
||||
alias Pleroma.Object
|
||||
|
||||
@moduledoc "Ensure a re: is prepended on replies to a post with a Subject"
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
alias Pleroma.Object
|
||||
|
||||
use Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
@reply_prefix Regex.compile!("^re:[[:space:]]*", [:caseless])
|
||||
|
||||
def history_awareness, do: :auto
|
||||
|
|
|
|||
|
|
@ -4,12 +4,15 @@
|
|||
|
||||
defmodule Pleroma.Web.ActivityPub.MRF.FollowBotPolicy do
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
alias Pleroma.Config
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web.CommonAPI
|
||||
|
||||
require Logger
|
||||
|
||||
use Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
@impl true
|
||||
def filter(activity) do
|
||||
with follower_nickname <- Config.get([:mrf_follow_bot, :follower_nickname]),
|
||||
|
|
|
|||
|
|
@ -3,9 +3,12 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.MRF.ForceBotUnlistedPolicy do
|
||||
alias Pleroma.User
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
@moduledoc "Remove bot posts from federated timeline"
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
alias Pleroma.User
|
||||
|
||||
use Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
require Pleroma.Constants
|
||||
|
||||
|
|
|
|||
|
|
@ -3,13 +3,14 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.MRF.ForceMention do
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
require Pleroma.Constants
|
||||
|
||||
alias Pleroma.Config
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.User
|
||||
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
use Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
defp get_author(url) do
|
||||
with %Object{data: %{"actor" => actor}} <- Object.normalize(url, fetch: false),
|
||||
|
|
|
|||
|
|
@ -3,13 +3,15 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.MRF.ForceMentionsInContent do
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
require Pleroma.Constants
|
||||
|
||||
alias Pleroma.Formatter
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.User
|
||||
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
use Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
@impl true
|
||||
def history_awareness, do: :auto
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.MRF.HashtagPolicy do
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
require Pleroma.Constants
|
||||
|
||||
alias Pleroma.Config
|
||||
|
|
@ -14,7 +16,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.HashtagPolicy do
|
|||
Note: This MRF Policy is always enabled, if you want to disable it you have to set empty lists.
|
||||
"""
|
||||
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
use Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
@impl true
|
||||
def history_awareness, do: :manual
|
||||
|
|
|
|||
|
|
@ -3,13 +3,14 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.MRF.HellthreadPolicy do
|
||||
@moduledoc "Block activities with too much mentions (configurable)"
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
alias Pleroma.User
|
||||
|
||||
require Pleroma.Constants
|
||||
|
||||
@moduledoc "Block activities with too much mentions (configurable)"
|
||||
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
use Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
defp delist_activity(activity, threshold) when threshold > 0 do
|
||||
follower_collection = User.get_cached_by_ap_id(activity["actor"]).follower_address
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.InlineQuotePolicy do
|
|||
@moduledoc "Force a quote line into the message content."
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
use Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
defp build_inline_quote(template, url) do
|
||||
quote_line = String.replace(template, "{url}", "<a href=\"#{url}\">#{url}</a>")
|
||||
|
||||
|
|
|
|||
|
|
@ -3,13 +3,14 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.MRF.KeywordPolicy do
|
||||
@moduledoc "Reject or Word-Replace activities with a keyword or regex"
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
require Pleroma.Constants
|
||||
|
||||
alias Pleroma.Web.ActivityPub.MRF.Utils
|
||||
|
||||
@moduledoc "Reject or Word-Replace activities with a keyword or regex"
|
||||
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
use Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
defp string_matches?(string, pattern) when is_binary(pattern) do
|
||||
String.contains?(string, pattern)
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy do
|
|||
@moduledoc "Preloads any attachments in the MediaProxy cache by prefetching them"
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
use Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
alias Pleroma.HTTP
|
||||
alias Pleroma.Web.MediaProxy
|
||||
|
||||
|
|
|
|||
|
|
@ -4,9 +4,10 @@
|
|||
|
||||
defmodule Pleroma.Web.ActivityPub.MRF.MentionPolicy do
|
||||
@moduledoc "Block activities which mention a user"
|
||||
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
use Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
@impl true
|
||||
def filter(%{"type" => "Create"} = activity) do
|
||||
reject_actors = Pleroma.Config.get([:mrf_mention, :actors], [])
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.NoEmptyPolicy do
|
|||
@moduledoc "Filter local activities which have no content"
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
use Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
alias Pleroma.Web.Endpoint
|
||||
|
||||
@impl true
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.NoOpPolicy do
|
|||
@moduledoc "Does nothing (lets the messages go through unmodified)"
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
use Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
@impl true
|
||||
def filter(activity) do
|
||||
{:ok, activity}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.NoPlaceholderTextPolicy do
|
|||
@moduledoc "Ensure no content placeholder is present (such as the dot from mastodon)"
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
use Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
@impl true
|
||||
def history_awareness, do: :auto
|
||||
|
||||
|
|
|
|||
|
|
@ -4,9 +4,11 @@
|
|||
|
||||
defmodule Pleroma.Web.ActivityPub.MRF.NormalizeMarkup do
|
||||
@moduledoc "Scrub configured hypertext markup"
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
alias Pleroma.HTML
|
||||
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
use Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
@impl true
|
||||
def history_awareness, do: :auto
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.NsfwApiPolicy do
|
|||
- `unlist`: Unlist all detected NSFW content? Default: `false`
|
||||
- `reject`: Reject all detected NSFW content (takes precedence)? Default: `false`
|
||||
"""
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
alias Pleroma.Config
|
||||
alias Pleroma.Constants
|
||||
alias Pleroma.HTTP
|
||||
|
|
@ -46,7 +48,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.NsfwApiPolicy do
|
|||
require Logger
|
||||
require Pleroma.Constants
|
||||
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
use Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
@policy :mrf_nsfw_api
|
||||
|
||||
def build_request_url(url) do
|
||||
|
|
|
|||
|
|
@ -3,13 +3,15 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.MRF.ObjectAgePolicy do
|
||||
@moduledoc "Filter activities depending on their age"
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
alias Pleroma.Config
|
||||
alias Pleroma.User
|
||||
|
||||
require Pleroma.Constants
|
||||
|
||||
@moduledoc "Filter activities depending on their age"
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
use Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
defp check_date(%{"object" => %{"published" => published}} = activity) do
|
||||
with %DateTime{} = now <- DateTime.utc_now(),
|
||||
|
|
|
|||
|
|
@ -15,4 +15,12 @@ defmodule Pleroma.Web.ActivityPub.MRF.Policy do
|
|||
}
|
||||
@callback history_awareness() :: :auto | :manual
|
||||
@optional_callbacks config_description: 0, history_awareness: 0, id_filter: 1
|
||||
|
||||
defmacro __using__(_) do
|
||||
quote do
|
||||
# Otherwise Pleroma.Docs.Generator.list_behaviour_implementations fails
|
||||
# since the Elixir compiler doesn't automatically load the module since v1.19.
|
||||
@compile {:autoload, true}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -6,11 +6,13 @@ defmodule Pleroma.Web.ActivityPub.MRF.QuietReply do
|
|||
@moduledoc """
|
||||
QuietReply alters the scope of activities from local users when replying by enforcing them to be "Unlisted" or "Quiet Public". This delivers the activity to all the expected recipients and instances, but it will not be published in the Federated / The Whole Known Network timelines. It will still be published to the Home timelines of the user's followers and visible to anyone who opens the thread.
|
||||
"""
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
require Pleroma.Constants
|
||||
|
||||
alias Pleroma.User
|
||||
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
use Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
@impl true
|
||||
def history_awareness, do: :auto
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.QuoteToLinkTagPolicy do
|
|||
@moduledoc "Force a Link tag for posts quoting another post. (may break outgoing federation of quote posts with older Pleroma versions)"
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
use Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes
|
||||
|
||||
require Pleroma.Constants
|
||||
|
|
|
|||
|
|
@ -4,11 +4,12 @@
|
|||
|
||||
defmodule Pleroma.Web.ActivityPub.MRF.RejectNonPublic do
|
||||
@moduledoc "Rejects non-public (followers-only, direct) activities"
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
alias Pleroma.Config
|
||||
alias Pleroma.User
|
||||
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
use Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
require Pleroma.Constants
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.RemoteReportPolicy do
|
|||
@moduledoc "Drop remote reports if they don't contain enough information."
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
use Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
alias Pleroma.Config
|
||||
|
||||
@impl true
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do
|
|||
@moduledoc "Filter activities depending on their origin instance"
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
use Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
alias Pleroma.Config
|
||||
alias Pleroma.FollowingRelationship
|
||||
alias Pleroma.User
|
||||
|
|
|
|||
|
|
@ -3,12 +3,14 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.MRF.StealEmojiPolicy do
|
||||
@moduledoc "Detect new emojis by their shortcode and steals them"
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
require Logger
|
||||
|
||||
alias Pleroma.Config
|
||||
|
||||
@moduledoc "Detect new emojis by their shortcode and steals them"
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
use Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
defp accept_host?(host), do: host in Config.get([:mrf_steal_emoji, :hosts], [])
|
||||
|
||||
|
|
|
|||
|
|
@ -3,12 +3,14 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.MRF.SubchainPolicy do
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
alias Pleroma.Config
|
||||
alias Pleroma.Web.ActivityPub.MRF
|
||||
|
||||
require Logger
|
||||
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
use Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
defp lookup_subchain(actor) do
|
||||
with matches <- Config.get([:mrf_subchain, :match_actor]),
|
||||
|
|
|
|||
|
|
@ -3,8 +3,6 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.MRF.TagPolicy do
|
||||
alias Pleroma.User
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
@moduledoc """
|
||||
Apply policies based on user tags
|
||||
|
||||
|
|
@ -18,6 +16,11 @@ defmodule Pleroma.Web.ActivityPub.MRF.TagPolicy do
|
|||
- `mrf_tag:disable-remote-subscription`: Reject non-local follow requests
|
||||
- `mrf_tag:disable-any-subscription`: Reject any follow requests
|
||||
"""
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
alias Pleroma.User
|
||||
|
||||
use Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
require Pleroma.Constants
|
||||
|
||||
|
|
|
|||
|
|
@ -3,11 +3,13 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.MRF.UserAllowListPolicy do
|
||||
alias Pleroma.Config
|
||||
|
||||
@moduledoc "Accept-list of users from specified instances"
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
alias Pleroma.Config
|
||||
|
||||
use Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
defp filter_by_list(activity, []), do: {:ok, activity}
|
||||
|
||||
defp filter_by_list(%{"actor" => actor} = activity, allow_list) do
|
||||
|
|
|
|||
|
|
@ -4,9 +4,10 @@
|
|||
|
||||
defmodule Pleroma.Web.ActivityPub.MRF.VocabularyPolicy do
|
||||
@moduledoc "Filter activities which belong to certain activity vocabularies"
|
||||
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
use Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
@impl true
|
||||
def filter(%{"type" => "Undo", "object" => object} = activity) do
|
||||
with {:ok, _} <- filter(object) do
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ defmodule Pleroma.Web.ActivityPub.UserView do
|
|||
capabilities =
|
||||
if is_boolean(user.accepts_chat_messages) do
|
||||
%{
|
||||
"acceptsChatMessages" => user.accepts_chat_messages
|
||||
"acceptsChatMessages" => Pleroma.Chat.enabled?() and user.accepts_chat_messages
|
||||
}
|
||||
else
|
||||
%{}
|
||||
|
|
|
|||
|
|
@ -71,7 +71,10 @@ defmodule Pleroma.Web.AdminAPI.ConfigController do
|
|||
end
|
||||
|
||||
def descriptions(conn, _params) do
|
||||
descriptions = Enum.filter(Pleroma.Docs.JSON.compiled_descriptions(), &whitelisted_config?/1)
|
||||
descriptions =
|
||||
Pleroma.Docs.JSON.compiled_descriptions()
|
||||
|> Enum.filter(&allowed_config?(&1, :whitelist))
|
||||
|> Enum.reject(&allowed_config?(&1, :blacklist))
|
||||
|
||||
json(conn, translate_descriptions(descriptions))
|
||||
end
|
||||
|
|
@ -132,7 +135,8 @@ defmodule Pleroma.Web.AdminAPI.ConfigController do
|
|||
with :ok <- configurable_from_database() do
|
||||
results =
|
||||
configs
|
||||
|> Enum.filter(&whitelisted_config?/1)
|
||||
|> Enum.filter(&allowed_config?(&1, :whitelist))
|
||||
|> Enum.reject(&allowed_config?(&1, :blacklist))
|
||||
|> Enum.map(fn
|
||||
%{group: group, key: key, delete: true} = params ->
|
||||
ConfigDB.delete(%{group: group, key: key, subkeys: params[:subkeys]})
|
||||
|
|
@ -174,27 +178,34 @@ defmodule Pleroma.Web.AdminAPI.ConfigController do
|
|||
end
|
||||
end
|
||||
|
||||
defp whitelisted_config?(":pleroma", ":database_config_whitelist"), do: false
|
||||
defp allowed_config?(":pleroma", ":database_config_whitelist", _), do: true
|
||||
defp allowed_config?(":pleroma", ":database_config_blacklist", _), do: true
|
||||
|
||||
defp whitelisted_config?(group, key) do
|
||||
if whitelisted_configs = Config.get(:database_config_whitelist) do
|
||||
Enum.any?(whitelisted_configs, fn
|
||||
{whitelisted_group} ->
|
||||
group == inspect(whitelisted_group)
|
||||
defp allowed_config?(group, key, mode) do
|
||||
configs =
|
||||
case mode do
|
||||
:whitelist -> Config.get(:database_config_whitelist)
|
||||
:blacklist -> Config.get(:database_config_blacklist)
|
||||
end
|
||||
|
||||
{whitelisted_group, whitelisted_key} ->
|
||||
group == inspect(whitelisted_group) && key == inspect(whitelisted_key)
|
||||
if configs do
|
||||
Enum.any?(configs, fn
|
||||
{allowed_group} ->
|
||||
group == inspect(allowed_group)
|
||||
|
||||
{allowed_group, allowed_key} ->
|
||||
group == inspect(allowed_group) && key == inspect(allowed_key)
|
||||
end)
|
||||
else
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
defp whitelisted_config?(%{group: group, key: key}) do
|
||||
whitelisted_config?(group, key)
|
||||
defp allowed_config?(%{group: group, key: key}, mode) do
|
||||
allowed_config?(group, key, mode)
|
||||
end
|
||||
|
||||
defp whitelisted_config?(%{group: group} = config) do
|
||||
whitelisted_config?(group, config[:key])
|
||||
defp allowed_config?(%{group: group} = config, mode) do
|
||||
allowed_config?(group, config[:key], mode)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -31,7 +31,8 @@ defmodule Pleroma.Web.ApiSpec.ChatOperation do
|
|||
"The updated chat",
|
||||
"application/json",
|
||||
Chat
|
||||
)
|
||||
),
|
||||
404 => Operation.response("Not Found", "application/json", ApiError)
|
||||
},
|
||||
security: [
|
||||
%{
|
||||
|
|
@ -56,7 +57,8 @@ defmodule Pleroma.Web.ApiSpec.ChatOperation do
|
|||
"The read ChatMessage",
|
||||
"application/json",
|
||||
ChatMessage
|
||||
)
|
||||
),
|
||||
404 => Operation.response("Not Found", "application/json", ApiError)
|
||||
},
|
||||
security: [
|
||||
%{
|
||||
|
|
@ -87,7 +89,8 @@ defmodule Pleroma.Web.ApiSpec.ChatOperation do
|
|||
"The existing chat",
|
||||
"application/json",
|
||||
Chat
|
||||
)
|
||||
),
|
||||
404 => Operation.response("Not Found", "application/json", ApiError)
|
||||
},
|
||||
security: [
|
||||
%{
|
||||
|
|
@ -118,7 +121,8 @@ defmodule Pleroma.Web.ApiSpec.ChatOperation do
|
|||
"The created or existing chat",
|
||||
"application/json",
|
||||
Chat
|
||||
)
|
||||
),
|
||||
404 => Operation.response("Not Found", "application/json", ApiError)
|
||||
},
|
||||
security: [
|
||||
%{
|
||||
|
|
@ -146,7 +150,8 @@ defmodule Pleroma.Web.ApiSpec.ChatOperation do
|
|||
Operation.parameter(:pinned, :query, BooleanLike.schema(), "Include only pinned chats")
|
||||
],
|
||||
responses: %{
|
||||
200 => Operation.response("The chats of the user", "application/json", chats_response())
|
||||
200 => Operation.response("The chats of the user", "application/json", chats_response()),
|
||||
404 => Operation.response("Not Found", "application/json", ApiError)
|
||||
},
|
||||
security: [
|
||||
%{
|
||||
|
|
@ -172,7 +177,8 @@ defmodule Pleroma.Web.ApiSpec.ChatOperation do
|
|||
| pagination_params()
|
||||
],
|
||||
responses: %{
|
||||
200 => Operation.response("The chats of the user", "application/json", chats_response())
|
||||
200 => Operation.response("The chats of the user", "application/json", chats_response()),
|
||||
404 => Operation.response("Not Found", "application/json", ApiError)
|
||||
},
|
||||
security: [
|
||||
%{
|
||||
|
|
@ -224,6 +230,7 @@ defmodule Pleroma.Web.ApiSpec.ChatOperation do
|
|||
ChatMessage
|
||||
),
|
||||
400 => Operation.response("Bad Request", "application/json", ApiError),
|
||||
404 => Operation.response("Not Found", "application/json", ApiError),
|
||||
422 => Operation.response("MRF Rejection", "application/json", ApiError)
|
||||
},
|
||||
security: [
|
||||
|
|
@ -249,7 +256,8 @@ defmodule Pleroma.Web.ApiSpec.ChatOperation do
|
|||
"The deleted ChatMessage",
|
||||
"application/json",
|
||||
ChatMessage
|
||||
)
|
||||
),
|
||||
404 => Operation.response("Not Found", "application/json", ApiError)
|
||||
},
|
||||
security: [
|
||||
%{
|
||||
|
|
@ -268,7 +276,8 @@ defmodule Pleroma.Web.ApiSpec.ChatOperation do
|
|||
Operation.parameter(:id, :path, :string, "The id of the chat", required: true)
|
||||
],
|
||||
responses: %{
|
||||
200 => Operation.response("The existing chat", "application/json", Chat)
|
||||
200 => Operation.response("The existing chat", "application/json", Chat),
|
||||
404 => Operation.response("Not Found", "application/json", ApiError)
|
||||
},
|
||||
security: [
|
||||
%{
|
||||
|
|
@ -287,7 +296,8 @@ defmodule Pleroma.Web.ApiSpec.ChatOperation do
|
|||
Operation.parameter(:id, :path, :string, "The id of the chat", required: true)
|
||||
],
|
||||
responses: %{
|
||||
200 => Operation.response("The existing chat", "application/json", Chat)
|
||||
200 => Operation.response("The existing chat", "application/json", Chat),
|
||||
404 => Operation.response("Not Found", "application/json", ApiError)
|
||||
},
|
||||
security: [
|
||||
%{
|
||||
|
|
|
|||
|
|
@ -139,6 +139,8 @@ defmodule Pleroma.Web.Endpoint do
|
|||
from: {:pleroma, "priv/static/adminfe/"}
|
||||
)
|
||||
|
||||
plug(Pleroma.Web.Plugs.StaticNotFoundPlug)
|
||||
|
||||
# Code reloading can be explicitly enabled under the
|
||||
# :code_reloader configuration of your endpoint.
|
||||
if code_reloading? do
|
||||
|
|
|
|||
|
|
@ -89,7 +89,8 @@ defmodule Pleroma.Web.Federator do
|
|||
|
||||
# Job Worker Callbacks
|
||||
|
||||
@spec perform(atom(), any()) :: {:ok, any()} | {:error, any()}
|
||||
@impl true
|
||||
@spec perform(atom(), any()) :: :ok | {:ok, any()} | {:error, any()}
|
||||
def perform(:publish_one, params) do
|
||||
Publisher.prepare_one(params)
|
||||
|> Publisher.publish_one()
|
||||
|
|
|
|||
|
|
@ -3,5 +3,6 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.Federator.Publishing do
|
||||
@callback perform(atom(), any()) :: :ok | {:ok, any()} | {:error, any()}
|
||||
@callback publish(map()) :: any()
|
||||
end
|
||||
|
|
|
|||
|
|
@ -38,6 +38,20 @@ defmodule Pleroma.Web.Feed.FeedView do
|
|||
end
|
||||
end
|
||||
|
||||
def most_recent_update([], :rss), do: nil
|
||||
|
||||
def most_recent_update(activities, :rss) do
|
||||
activities
|
||||
|> Enum.map(fn activity ->
|
||||
case activity.object do
|
||||
%Object{updated_at: updated_at} -> updated_at
|
||||
_ -> activity.updated_at
|
||||
end
|
||||
end)
|
||||
|> Enum.max_by(&NaiveDateTime.to_erl/1)
|
||||
|> to_rfc2822()
|
||||
end
|
||||
|
||||
def most_recent_update(activities, user, :atom) do
|
||||
(List.first(activities) || user).updated_at
|
||||
|> to_rfc3339()
|
||||
|
|
@ -97,6 +111,67 @@ defmodule Pleroma.Web.Feed.FeedView do
|
|||
end
|
||||
end
|
||||
|
||||
def rss_content_encoded(data) do
|
||||
data
|
||||
|> feed_content_encoded()
|
||||
|> String.replace("]]>", "]]>")
|
||||
end
|
||||
|
||||
def atom_content_encoded(data), do: feed_content_encoded(data)
|
||||
|
||||
defp feed_content_encoded(data) do
|
||||
base_content =
|
||||
case activity_content(data) do
|
||||
"" ->
|
||||
(data["summary"] || data["type"] || "")
|
||||
|> escape()
|
||||
|
||||
content ->
|
||||
content
|
||||
end
|
||||
|
||||
attachments_html =
|
||||
if sensitive?(data) do
|
||||
""
|
||||
else
|
||||
(data["attachment"] || [])
|
||||
|> Enum.map(&rss_attachment_preview/1)
|
||||
|> Enum.reject(&(&1 == ""))
|
||||
|> Enum.join("<br/><br/>")
|
||||
end
|
||||
|
||||
[base_content, attachments_html]
|
||||
|> Enum.reject(&(&1 == ""))
|
||||
|> Enum.join("<br/><br/>")
|
||||
end
|
||||
|
||||
defp rss_attachment_preview(attachment) do
|
||||
href = attachment_href(attachment)
|
||||
|
||||
if is_binary(href) and href != "" do
|
||||
media_type = attachment_type(attachment) || "application/octet-stream"
|
||||
escaped_href = escape(href)
|
||||
name = attachment["name"] || "Attachment"
|
||||
escaped_name = escape(name)
|
||||
|
||||
cond do
|
||||
String.starts_with?(media_type, "image/") ->
|
||||
~s(<p><img src="#{escaped_href}" alt="#{escaped_name}" loading="lazy"/></p>)
|
||||
|
||||
String.starts_with?(media_type, "video/") ->
|
||||
~s(<p><video controls preload="metadata" src="#{escaped_href}"></video></p><p><a href="#{escaped_href}">#{escaped_name}</a></p>)
|
||||
|
||||
String.starts_with?(media_type, "audio/") ->
|
||||
~s(<p><audio controls preload="metadata" src="#{escaped_href}"></audio></p><p><a href="#{escaped_href}">#{escaped_name}</a></p>)
|
||||
|
||||
true ->
|
||||
~s(<p><a href="#{escaped_href}">#{escaped_name}</a></p>)
|
||||
end
|
||||
else
|
||||
""
|
||||
end
|
||||
end
|
||||
|
||||
def activity_content(%{"content" => content}) do
|
||||
content
|
||||
|> String.replace(~r/[\n\r]/, "")
|
||||
|
|
@ -106,16 +181,104 @@ defmodule Pleroma.Web.Feed.FeedView do
|
|||
|
||||
def activity_context(activity), do: escape(activity.data["context"])
|
||||
|
||||
def sensitive?(data), do: data["sensitive"] in [true, "true"]
|
||||
|
||||
def feed_self_url(conn) do
|
||||
conn
|
||||
|> Phoenix.Controller.current_url()
|
||||
|> escape()
|
||||
end
|
||||
|
||||
def activity_link(activity, data) do
|
||||
cond do
|
||||
activity.local -> data["id"] || data["url"]
|
||||
true -> data["external_url"] || data["id"] || data["url"]
|
||||
end
|
||||
end
|
||||
|
||||
def attachment_href(attachment) do
|
||||
attachment["url"]
|
||||
|> hd()
|
||||
attachment
|
||||
|> attachment_url_data()
|
||||
|> Map.get("href")
|
||||
end
|
||||
|
||||
def attachment_type(attachment) do
|
||||
attachment["url"]
|
||||
|> hd()
|
||||
|> Map.get("mediaType")
|
||||
attachment
|
||||
|> attachment_url_data()
|
||||
|> Map.get("mediaType") || attachment["mediaType"]
|
||||
end
|
||||
|
||||
def attachment_size(attachment) do
|
||||
attachment
|
||||
|> attachment_url_data()
|
||||
|> Map.get("size", 0)
|
||||
end
|
||||
|
||||
def attachment_size_positive(attachment) do
|
||||
case attachment_size(attachment) do
|
||||
size when is_integer(size) and size > 0 ->
|
||||
size
|
||||
|
||||
size when is_binary(size) ->
|
||||
case Integer.parse(size) do
|
||||
{parsed, ""} when parsed > 0 -> parsed
|
||||
_ -> nil
|
||||
end
|
||||
|
||||
_ ->
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
def attachment_medium(attachment) do
|
||||
case attachment_type(attachment) do
|
||||
"image/" <> _rest -> "image"
|
||||
"video/" <> _rest -> "video"
|
||||
"audio/" <> _rest -> "audio"
|
||||
_ -> "document"
|
||||
end
|
||||
end
|
||||
|
||||
def rss_enclosure_attachment(attachments) do
|
||||
Enum.find(attachments || [], &(not is_nil(attachment_size_positive(&1))))
|
||||
end
|
||||
|
||||
def attachment_description(attachment) do
|
||||
attachment["name"] || ""
|
||||
end
|
||||
|
||||
def media_content_xml(_attachment, sensitive) when sensitive in [true, "true"], do: ""
|
||||
|
||||
def media_content_xml(attachment, _sensitive) do
|
||||
href = escape(attachment_href(attachment) || "")
|
||||
type = escape(attachment_type(attachment) || "application/octet-stream")
|
||||
medium = escape(attachment_medium(attachment))
|
||||
|
||||
file_size_attr =
|
||||
case attachment_size_positive(attachment) do
|
||||
size when is_integer(size) -> ~s( fileSize="#{size}")
|
||||
_ -> ""
|
||||
end
|
||||
|
||||
case attachment_description(attachment) do
|
||||
"" ->
|
||||
~s(<media:content url="#{href}" type="#{type}"#{file_size_attr} medium="#{medium}"/>\n)
|
||||
|
||||
description ->
|
||||
"""
|
||||
<media:content url="#{href}" type="#{type}"#{file_size_attr} medium="#{medium}">
|
||||
<media:description type="plain">#{escape(description)}</media:description>
|
||||
</media:content>
|
||||
"""
|
||||
end
|
||||
end
|
||||
|
||||
defp attachment_url_data(attachment) do
|
||||
case attachment["url"] do
|
||||
[first | _] when is_map(first) -> first
|
||||
%{} = map -> map
|
||||
_ -> %{}
|
||||
end
|
||||
end
|
||||
|
||||
def get_href(id) do
|
||||
|
|
|
|||
|
|
@ -716,7 +716,10 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
|
|||
end
|
||||
end
|
||||
|
||||
defp put_application(params, %{assigns: %{token: %Token{user: %User{} = user} = token}} = _conn) do
|
||||
defp put_application(
|
||||
params,
|
||||
%{assigns: %{token: %Token{} = token, user: %User{} = user}} = _conn
|
||||
) do
|
||||
if user.disclose_client do
|
||||
%{client_name: client_name, website: website} = Repo.preload(token, :app).app
|
||||
Map.put(params, :generator, %{type: "Application", name: client_name, url: website})
|
||||
|
|
|
|||
|
|
@ -385,6 +385,15 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPI do
|
|||
|> cast_params()
|
||||
|> Map.update(:include_types, [], fn include_types -> include_types end)
|
||||
|
||||
if "pleroma:chat_mention" in options.include_types and not Pleroma.Chat.enabled?() do
|
||||
options
|
||||
|> Map.update(:include_types, [], fn include_types ->
|
||||
List.delete(include_types, "pleroma:chat_mention")
|
||||
end)
|
||||
else
|
||||
options
|
||||
end
|
||||
|
||||
if ("pleroma:report" not in options.include_types and
|
||||
User.privileged?(user, :reports_manage_reports)) or
|
||||
User.privileged?(user, :reports_manage_reports) do
|
||||
|
|
|
|||
|
|
@ -287,6 +287,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
|
|||
user.last_status_at &&
|
||||
user.last_status_at |> NaiveDateTime.to_date() |> Date.to_iso8601()
|
||||
|
||||
accepts_chat_messages = Pleroma.Chat.enabled?() and user.accepts_chat_messages
|
||||
|
||||
%{
|
||||
id: to_string(user.id),
|
||||
username: username_from_nickname(user.nickname),
|
||||
|
|
@ -336,7 +338,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
|
|||
relationship: relationship,
|
||||
skip_thread_containment: user.skip_thread_containment,
|
||||
background_image: image_url(user.background) |> MediaProxy.url(),
|
||||
accepts_chat_messages: user.accepts_chat_messages,
|
||||
accepts_chat_messages: accepts_chat_messages,
|
||||
favicon: favicon,
|
||||
avatar_description: avatar_description,
|
||||
header_description: header_description
|
||||
|
|
@ -391,6 +393,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
|
|||
|> Kernel.put_in([:source, :pleroma, :show_role], user.show_role)
|
||||
|> Kernel.put_in([:source, :pleroma, :no_rich_text], user.no_rich_text)
|
||||
|> Kernel.put_in([:source, :pleroma, :show_birthday], user.show_birthday)
|
||||
|> Kernel.put_in([:source, :pleroma, :accepts_chat_messages], user.accepts_chat_messages)
|
||||
end
|
||||
|
||||
defp maybe_put_settings(data, _, _, _), do: data
|
||||
|
|
|
|||
|
|
@ -202,8 +202,12 @@ defmodule Pleroma.Web.MastodonAPI.InstanceView do
|
|||
end,
|
||||
"pleroma_emoji_reactions",
|
||||
"pleroma_custom_emoji_reactions",
|
||||
"pleroma_chat_messages",
|
||||
"pleroma:pin_chats",
|
||||
if Pleroma.Chat.enabled?() do
|
||||
"pleroma_chat_messages"
|
||||
end,
|
||||
if Pleroma.Chat.enabled?() do
|
||||
"pleroma:pin_chats"
|
||||
end,
|
||||
if Config.get([:instance, :show_reactions]) do
|
||||
"exposable_reactions"
|
||||
end,
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ defmodule Pleroma.Web.PleromaAPI.ChatController do
|
|||
)
|
||||
|
||||
plug(Pleroma.Web.ApiSpec.CastAndValidate, replace_params: false)
|
||||
plug(:ensure_chats_enabled)
|
||||
|
||||
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.ChatOperation
|
||||
|
||||
|
|
@ -244,4 +245,16 @@ defmodule Pleroma.Web.PleromaAPI.ChatController do
|
|||
_ -> nil
|
||||
end
|
||||
end
|
||||
|
||||
defp ensure_chats_enabled(conn, _opts) do
|
||||
if Chat.enabled?() do
|
||||
conn
|
||||
else
|
||||
conn
|
||||
|> put_status(:not_found)
|
||||
|> put_view(Pleroma.Web.ErrorView)
|
||||
|> render("404.json")
|
||||
|> halt()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
defmodule Pleroma.Web.Plugs.EnsureHostMatchesPlug do
|
||||
@moduledoc "Ensures Host header matches instance"
|
||||
@behaviour Plug
|
||||
|
||||
alias Pleroma.Web.Endpoint
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
defmodule Pleroma.Web.Plugs.InstanceStatic do
|
||||
require Pleroma.Constants
|
||||
import Plug.Conn, only: [put_resp_header: 3, put_status: 2, send_resp: 3, halt: 1]
|
||||
import Plug.Conn, only: [put_resp_header: 3]
|
||||
|
||||
@moduledoc """
|
||||
This is a shim to call `Plug.Static` but with runtime `from` configuration.
|
||||
|
|
@ -51,37 +51,10 @@ defmodule Pleroma.Web.Plugs.InstanceStatic do
|
|||
|> Map.put(:from, from)
|
||||
|> Map.put(:content_types, false)
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> set_content_type(conn.request_path)
|
||||
|> Plug.Static.call(opts)
|
||||
conn = set_content_type(conn, conn.request_path)
|
||||
|
||||
if conn.halted do
|
||||
conn
|
||||
else
|
||||
path = String.trim_leading(conn.request_path, "/")
|
||||
|
||||
if not File.exists?(file_path(path)) do
|
||||
conn
|
||||
|> put_status(:not_found)
|
||||
|> send_404()
|
||||
|> halt()
|
||||
else
|
||||
conn
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
defp send_404(conn) do
|
||||
if String.ends_with?(String.downcase(conn.request_path), ".json") do
|
||||
conn
|
||||
|> put_resp_header("content-type", "application/json")
|
||||
|> send_resp(404, Jason.encode!(%{error: "not found"}))
|
||||
else
|
||||
conn
|
||||
|> put_resp_header("content-type", "text/plain")
|
||||
|> send_resp(404, "Not found")
|
||||
end
|
||||
# Call Plug.Static with our sanitized content-type
|
||||
Plug.Static.call(conn, opts)
|
||||
end
|
||||
|
||||
defp set_content_type(conn, "/emoji/" <> filepath) do
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ defmodule Pleroma.Web.Plugs.OAuthPlug do
|
|||
where: t.token == ^token
|
||||
)
|
||||
|
||||
with %Token{user_id: user_id} = token_record <- Repo.one(token_query) |> Repo.preload(:user),
|
||||
with %Token{user_id: user_id} = token_record <- Repo.one(token_query),
|
||||
false <- is_nil(user_id),
|
||||
%User{} = user <- User.get_cached_by_id(user_id) do
|
||||
{:ok, user, token_record}
|
||||
|
|
|
|||
38
lib/pleroma/web/plugs/static_not_found_plug.ex
Normal file
38
lib/pleroma/web/plugs/static_not_found_plug.ex
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2026 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.Plugs.StaticNotFoundPlug do
|
||||
@moduledoc """
|
||||
A small plug that enforces returning 404 on static files when they don't exist.
|
||||
"""
|
||||
@behaviour Plug
|
||||
|
||||
require Pleroma.Constants
|
||||
import Plug.Conn, only: [put_resp_header: 3, send_resp: 3, halt: 1]
|
||||
|
||||
def init(opts), do: opts
|
||||
|
||||
for only <- Pleroma.Constants.static_only_files() do
|
||||
def call(%{request_path: "/" <> unquote(only) <> _} = conn, _opts) do
|
||||
send_404(conn)
|
||||
end
|
||||
end
|
||||
|
||||
def call(conn, _) do
|
||||
conn
|
||||
end
|
||||
|
||||
defp send_404(conn) do
|
||||
if String.ends_with?(String.downcase(conn.request_path), ".json") do
|
||||
conn
|
||||
|> put_resp_header("content-type", "application/json")
|
||||
|> send_resp(404, Jason.encode!(%{error: "not found"}))
|
||||
else
|
||||
conn
|
||||
|> put_resp_header("content-type", "text/plain")
|
||||
|> send_resp(404, "Not found")
|
||||
end
|
||||
|> halt()
|
||||
end
|
||||
end
|
||||
|
|
@ -195,6 +195,9 @@ defmodule Pleroma.Web.Streamer do
|
|||
recipients = MapSet.new(item.recipients)
|
||||
domain_blocks = Pleroma.Web.ActivityPub.MRF.subdomains_regex(user.domain_blocks)
|
||||
|
||||
following_ap_ids =
|
||||
if user.domain_blocks == [], do: [], else: User.get_cached_user_friends_ap_ids(user)
|
||||
|
||||
with parent <- Object.normalize(item, fetch: false) || item,
|
||||
true <- Enum.all?([blocked_ap_ids, muted_ap_ids], &(item.actor not in &1)),
|
||||
true <- item.data["type"] != "Announce" || item.actor not in reblog_muted_ap_ids,
|
||||
|
|
@ -205,8 +208,12 @@ defmodule Pleroma.Web.Streamer do
|
|||
true <- MapSet.disjoint?(recipients, recipient_blocks),
|
||||
%{host: item_host} <- URI.parse(item.actor),
|
||||
%{host: parent_host} <- URI.parse(parent.data["actor"]),
|
||||
false <- Pleroma.Web.ActivityPub.MRF.subdomain_match?(domain_blocks, item_host),
|
||||
false <- Pleroma.Web.ActivityPub.MRF.subdomain_match?(domain_blocks, parent_host),
|
||||
false <-
|
||||
item.actor not in following_ap_ids and
|
||||
Pleroma.Web.ActivityPub.MRF.subdomain_match?(domain_blocks, item_host),
|
||||
false <-
|
||||
parent.data["actor"] not in following_ap_ids and
|
||||
Pleroma.Web.ActivityPub.MRF.subdomain_match?(domain_blocks, parent_host),
|
||||
true <- thread_containment(item, user),
|
||||
false <- CommonAPI.thread_muted?(parent, user) do
|
||||
false
|
||||
|
|
@ -289,15 +296,17 @@ defmodule Pleroma.Web.Streamer do
|
|||
|
||||
defp do_stream(topic, {user, %MessageReference{} = cm_ref})
|
||||
when topic in ["user", "user:pleroma_chat"] do
|
||||
topic = "#{topic}:#{user.id}"
|
||||
if Pleroma.Chat.enabled?() do
|
||||
topic = "#{topic}:#{user.id}"
|
||||
|
||||
text = StreamerView.render("chat_update.json", %{chat_message_reference: cm_ref}, topic)
|
||||
text = StreamerView.render("chat_update.json", %{chat_message_reference: cm_ref}, topic)
|
||||
|
||||
Registry.dispatch(@registry, topic, fn list ->
|
||||
Enum.each(list, fn {pid, _auth} ->
|
||||
send(pid, {:text, text})
|
||||
Registry.dispatch(@registry, topic, fn list ->
|
||||
Enum.each(list, fn {pid, _auth} ->
|
||||
send(pid, {:text, text})
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
defp do_stream("user", %Activity{} = item) do
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
<entry>
|
||||
<activity:object-type>http://activitystrea.ms/schema/1.0/note</activity:object-type>
|
||||
<activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb>
|
||||
<id><%= @data["id"] %></id>
|
||||
<id><%= escape(@data["id"] || "") %></id>
|
||||
<title><%= activity_title(@data, Keyword.get(@feed_config, :post_title, %{})) %></title>
|
||||
<content type="html"><%= activity_description(@data) %></content>
|
||||
<content type="html"><%= escape(atom_content_encoded(@data)) %></content>
|
||||
<published><%= to_rfc3339(@data["published"]) %></published>
|
||||
<updated><%= to_rfc3339(@data["published"]) %></updated>
|
||||
<ostatus:conversation ref="<%= activity_context(@activity) %>">
|
||||
|
|
@ -15,35 +15,26 @@
|
|||
<summary><%= escape(@data["summary"]) %></summary>
|
||||
<% end %>
|
||||
|
||||
<%= if @activity.local do %>
|
||||
<link type="application/atom+xml" href='<%= @data["id"] %>' rel="self"/>
|
||||
<link type="text/html" href='<%= @data["id"] %>' rel="alternate"/>
|
||||
<% else %>
|
||||
<link type="text/html" href='<%= @data["external_url"] %>' rel="alternate"/>
|
||||
<% end %>
|
||||
<link type="text/html" href='<%= escape(activity_link(@activity, @data) || "") %>' rel="alternate"/>
|
||||
|
||||
<%= for tag <- Pleroma.Object.hashtags(@object) do %>
|
||||
<category term="<%= tag %>"></category>
|
||||
<% end %>
|
||||
|
||||
<%= for attachment <- @data["attachment"] || [] do %>
|
||||
<link rel="enclosure" href="<%= attachment_href(attachment) %>" type="<%= attachment_type(attachment) %>"/>
|
||||
<%= unless sensitive?(@data) do %>
|
||||
<%= for attachment <- @data["attachment"] || [] do %>
|
||||
<%= if size = attachment_size_positive(attachment) do %>
|
||||
<link rel="enclosure" href="<%= escape(attachment_href(attachment) || "") %>" type="<%= escape(attachment_type(attachment) || "application/octet-stream") %>" length="<%= size %>"/>
|
||||
<% else %>
|
||||
<link rel="enclosure" href="<%= escape(attachment_href(attachment) || "") %>" type="<%= escape(attachment_type(attachment) || "application/octet-stream") %>"/>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<%= if @data["inReplyTo"] do %>
|
||||
<thr:in-reply-to ref='<%= @data["inReplyTo"] %>' href='<%= get_href(@data["inReplyTo"]) %>'/>
|
||||
<% end %>
|
||||
|
||||
<%= for id <- @activity.recipients do %>
|
||||
<%= if id == Pleroma.Constants.as_public() do %>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/collection" href="http://activityschema.org/collection/public"/>
|
||||
<% else %>
|
||||
<%= unless Regex.match?(~r/^#{Pleroma.Web.Endpoint.url()}.+followers$/, id) do %>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/person" href="<%= id %>"/>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<%= for {emoji, file} <- @data["emoji"] || %{} do %>
|
||||
<link name="<%= emoji %>" rel="emoji" href="<%= file %>"/>
|
||||
<% end %>
|
||||
|
|
|
|||
|
|
@ -1,45 +1,34 @@
|
|||
<item>
|
||||
<activity:object-type>http://activitystrea.ms/schema/1.0/note</activity:object-type>
|
||||
<activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb>
|
||||
<guid><%= @data["id"] %></guid>
|
||||
<guid isPermaLink="true"><%= escape(@data["id"] || "") %></guid>
|
||||
<title><%= activity_title(@data, Keyword.get(@feed_config, :post_title, %{})) %></title>
|
||||
<description><%= activity_description(@data) %></description>
|
||||
<content:encoded><![CDATA[<%= rss_content_encoded(@data) %>]]></content:encoded>
|
||||
<pubDate><%= to_rfc2822(@data["published"]) %></pubDate>
|
||||
<ostatus:conversation ref="<%= activity_context(@activity) %>">
|
||||
<%= activity_context(@activity) %>
|
||||
</ostatus:conversation>
|
||||
|
||||
<%= if @activity.local do %>
|
||||
<link><%= @data["id"] %></link>
|
||||
<% else %>
|
||||
<link><%= @data["external_url"] %></link>
|
||||
<% end %>
|
||||
|
||||
<link rel="ostatus:conversation"><%= activity_context(@activity) %></link>
|
||||
<link><%= escape(activity_link(@activity, @data) || "") %></link>
|
||||
|
||||
<%= for tag <- Pleroma.Object.hashtags(@object) do %>
|
||||
<category term="<%= tag %>"></category>
|
||||
<%= if tag && tag != "" do %>
|
||||
<category><%= tag %></category>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<%= unless sensitive?(@data) do %>
|
||||
<%= with attachment when not is_nil(attachment) <- rss_enclosure_attachment(@data["attachment"]) do %>
|
||||
<enclosure url="<%= escape(attachment_href(attachment) || "") %>" type="<%= escape(attachment_type(attachment) || "application/octet-stream") %>" length="<%= attachment_size_positive(attachment) %>" />
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<%= for attachment <- @data["attachment"] || [] do %>
|
||||
<enclosure url="<%= attachment_href(attachment) %>" type="<%= attachment_type(attachment) %>" />
|
||||
<%= media_content_xml(attachment, sensitive?(@data)) %>
|
||||
<% end %>
|
||||
|
||||
<%= if @data["inReplyTo"] do %>
|
||||
<thr:in-reply-to ref='<%= @data["inReplyTo"] %>' href='<%= get_href(@data["inReplyTo"]) %>'/>
|
||||
<% end %>
|
||||
|
||||
<%= for id <- @activity.recipients do %>
|
||||
<%= if id == Pleroma.Constants.as_public() do %>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/collection">http://activityschema.org/collection/public</link>
|
||||
<% else %>
|
||||
<%= unless Regex.match?(~r/^#{Pleroma.Web.Endpoint.url()}.+followers$/, id) do %>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/person"><%= id %></link>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<%= for {emoji, file} <- @data["emoji"] || %{} do %>
|
||||
<link name="<%= emoji %>" rel="emoji"><%= file %></link>
|
||||
<% end %>
|
||||
</item>
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@
|
|||
|
||||
<%= render Phoenix.Controller.view_module(@conn), "_tag_author.atom", assigns %>
|
||||
|
||||
<id><%= @data["id"] %></id>
|
||||
<id><%= escape(@data["id"] || "") %></id>
|
||||
<title><%= activity_title(@data, Keyword.get(@feed_config, :post_title, %{})) %></title>
|
||||
<content type="html"><%= activity_description(@data) %></content>
|
||||
<content type="html"><%= escape(atom_content_encoded(@data)) %></content>
|
||||
<published><%= to_rfc3339(@data["published"]) %></published>
|
||||
<updated><%= to_rfc3339(@data["published"]) %></updated>
|
||||
<ostatus:conversation ref="<%= activity_context(@activity) %>">
|
||||
|
|
@ -15,34 +15,25 @@
|
|||
<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 %>
|
||||
<link type="application/atom+xml" href='<%= @data["id"] %>' rel="self"/>
|
||||
<link type="text/html" href='<%= @data["id"] %>' rel="alternate"/>
|
||||
<% else %>
|
||||
<link type="text/html" href='<%= @data["external_url"] %>' rel="alternate"/>
|
||||
<% end %>
|
||||
|
||||
<%= for id <- @activity.recipients do %>
|
||||
<%= if id == Pleroma.Constants.as_public() do %>
|
||||
<link rel="mentioned"
|
||||
ostatus:object-type="http://activitystrea.ms/schema/1.0/collection"
|
||||
href="http://activityschema.org/collection/public"/>
|
||||
<% else %>
|
||||
<%= unless Regex.match?(~r/^#{Pleroma.Web.Endpoint.url()}.+followers$/, id) do %>
|
||||
<link rel="mentioned"
|
||||
ostatus:object-type="http://activitystrea.ms/schema/1.0/person"
|
||||
href="<%= id %>" />
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<link type="text/html" href='<%= escape(activity_link(@activity, @data) || "") %>' rel="alternate"/>
|
||||
|
||||
<%= for tag <- Pleroma.Object.hashtags(@object) do %>
|
||||
<category term="<%= tag %>"></category>
|
||||
<% end %>
|
||||
|
||||
<%= unless sensitive?(@data) do %>
|
||||
<%= for attachment <- @data["attachment"] || [] do %>
|
||||
<%= if size = attachment_size_positive(attachment) do %>
|
||||
<link rel="enclosure" href="<%= escape(attachment_href(attachment) || "") %>" type="<%= escape(attachment_type(attachment) || "application/octet-stream") %>" length="<%= size %>"/>
|
||||
<% else %>
|
||||
<link rel="enclosure" href="<%= escape(attachment_href(attachment) || "") %>" type="<%= escape(attachment_type(attachment) || "application/octet-stream") %>"/>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<%= for {emoji, file} <- @data["emoji"] || %{} do %>
|
||||
<link name="<%= emoji %>" rel="emoji" href="<%= file %>"/>
|
||||
<% end %>
|
||||
|
|
|
|||
|
|
@ -1,14 +1,24 @@
|
|||
<item>
|
||||
<title><%= activity_title(@data, Keyword.get(@feed_config, :post_title, %{})) %></title>
|
||||
|
||||
|
||||
<guid isPermalink="true"><%= activity_context(@activity) %></guid>
|
||||
<link><%= activity_context(@activity) %></link>
|
||||
<guid isPermaLink="true"><%= escape(activity_link(@activity, @data) || "") %></guid>
|
||||
<link><%= escape(activity_link(@activity, @data) || "") %></link>
|
||||
<pubDate><%= to_rfc2822(@data["published"]) %></pubDate>
|
||||
|
||||
<title><%= activity_title(@data, Keyword.get(@feed_config, :post_title, %{})) %></title>
|
||||
<description><%= activity_description(@data) %></description>
|
||||
<%= for attachment <- @data["attachment"] || [] do %>
|
||||
<enclosure url="<%= attachment_href(attachment) %>" type="<%= attachment_type(attachment) %>"/>
|
||||
<content:encoded><![CDATA[<%= rss_content_encoded(@data) %>]]></content:encoded>
|
||||
|
||||
<%= unless sensitive?(@data) do %>
|
||||
<%= with attachment when not is_nil(attachment) <- rss_enclosure_attachment(@data["attachment"]) do %>
|
||||
<enclosure url="<%= escape(attachment_href(attachment) || "") %>" type="<%= escape(attachment_type(attachment) || "application/octet-stream") %>" length="<%= attachment_size_positive(attachment) %>"/>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<%= for attachment <- @data["attachment"] || [] do %>
|
||||
<%= media_content_xml(attachment, sensitive?(@data)) %>
|
||||
<% end %>
|
||||
|
||||
<%= for tag <- Pleroma.Object.hashtags(@object) do %>
|
||||
<%= if tag && tag != "" do %>
|
||||
<category><%= tag %></category>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</item>
|
||||
|
|
|
|||
|
|
@ -9,10 +9,12 @@
|
|||
|
||||
<id><%= Routes.tag_feed_url(@conn, :feed, @tag) <> ".atom" %></id>
|
||||
<title>#<%= @tag %></title>
|
||||
<subtitle><%= Gettext.dpgettext("static_pages", "tag feed description", "These are public toots tagged with #%{tag}. You can interact with them if you have an account anywhere in the fediverse.", tag: @tag) %></subtitle>
|
||||
<%= with subtitle when subtitle not in [nil, ""] <- Gettext.dpgettext("static_pages", "tag feed description", "These are public toots tagged with #%{tag}. You can interact with them if you have an account anywhere in the fediverse.", tag: @tag) do %>
|
||||
<subtitle><%= subtitle %></subtitle>
|
||||
<% end %>
|
||||
<logo><%= feed_logo() %></logo>
|
||||
<updated><%= most_recent_update(@activities) %></updated>
|
||||
<link rel="self" href="<%= "#{Routes.tag_feed_url(@conn, :feed, @tag)}.atom" %>" type="application/atom+xml"/>
|
||||
<updated><%= most_recent_update(@activities) || to_rfc3339(NaiveDateTime.utc_now()) %></updated>
|
||||
<link rel="self" href="<%= feed_self_url(@conn) %>" type="application/atom+xml"/>
|
||||
|
||||
<%= for activity <- @activities do %>
|
||||
<%= render Phoenix.Controller.view_module(@conn), "_tag_activity.atom", Map.merge(assigns, prepare_activity(activity, actor: true)) %>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rss version="2.0"
|
||||
xmlns:webfeeds="http://webfeeds.org/rss/1.0"
|
||||
xmlns:content="http://purl.org/rss/1.0/modules/content/"
|
||||
xmlns:media="http://search.yahoo.com/mrss/"
|
||||
xmlns:thr="http://purl.org/syndication/thread/1.0">
|
||||
<channel>
|
||||
|
||||
|
|
@ -8,7 +10,12 @@
|
|||
<description><%= Gettext.dpgettext("static_pages", "tag feed description", "These are public toots tagged with #%{tag}. You can interact with them if you have an account anywhere in the fediverse.", tag: @tag) %></description>
|
||||
<link><%= "#{Routes.tag_feed_url(@conn, :feed, @tag)}.rss" %></link>
|
||||
<webfeeds:logo><%= feed_logo() %></webfeeds:logo>
|
||||
<webfeeds:icon><%= feed_logo() %></webfeeds:icon>
|
||||
<webfeeds:accentColor>2b90d9</webfeeds:accentColor>
|
||||
<%= with last_build_date when not is_nil(last_build_date) <- most_recent_update(@activities, :rss) do %>
|
||||
<lastBuildDate><%= last_build_date %></lastBuildDate>
|
||||
<% end %>
|
||||
<generator><%= Pleroma.Application.named_version() %></generator>
|
||||
<%= for activity <- @activities do %>
|
||||
<%= render Phoenix.Controller.view_module(@conn), "_tag_activity.xml", Map.merge(assigns, prepare_activity(activity)) %>
|
||||
<% end %>
|
||||
|
|
|
|||
|
|
@ -8,10 +8,12 @@
|
|||
|
||||
<id><%= Routes.user_feed_url(@conn, :feed, @user.nickname) <> ".atom" %></id>
|
||||
<title><%= @user.nickname <> "'s timeline" %></title>
|
||||
<subtitle><%= escape(@user.bio) %></subtitle>
|
||||
<%= if @user.bio && @user.bio != "" do %>
|
||||
<subtitle><%= escape(@user.bio) %></subtitle>
|
||||
<% end %>
|
||||
<updated><%= most_recent_update(@activities, @user, :atom) %></updated>
|
||||
<logo><%= logo(@user) %></logo>
|
||||
<link rel="self" href="<%= "#{Routes.user_feed_url(@conn, :feed, @user.nickname)}.atom" %>" type="application/atom+xml"/>
|
||||
<link rel="self" href="<%= feed_self_url(@conn) %>" type="application/atom+xml"/>
|
||||
|
||||
<%= render Phoenix.Controller.view_module(@conn), "_author.atom", assigns %>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,26 +1,32 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<rss version="2.0"
|
||||
xmlns:atom="http://www.w3.org/2005/Atom"
|
||||
xmlns:content="http://purl.org/rss/1.0/modules/content/"
|
||||
xmlns:webfeeds="http://webfeeds.org/rss/1.0"
|
||||
xmlns:media="http://search.yahoo.com/mrss/"
|
||||
xmlns:thr="http://purl.org/syndication/thread/1.0"
|
||||
xmlns:activity="http://activitystrea.ms/spec/1.0/"
|
||||
xmlns:ostatus="http://ostatus.org/schema/1.0"
|
||||
xmlns:poco="http://portablecontacts.net/spec/1.0">
|
||||
<channel>
|
||||
<title><%= @user.nickname <> "'s timeline" %></title>
|
||||
<link><%= "#{Routes.user_feed_url(@conn, :feed, @user.nickname)}.rss" %></link>
|
||||
<atom:link href="<%= Routes.user_feed_url(@conn, :feed, @user.nickname) <> ".atom" %>"
|
||||
<atom:link href="<%= feed_self_url(@conn) %>"
|
||||
rel="self" type="application/rss+xml" />
|
||||
<link><%= "#{Routes.user_feed_url(@conn, :feed, @user.nickname)}.rss" %></link>
|
||||
<description><%= escape(@user.bio) %></description>
|
||||
<image>
|
||||
<url><%= logo(@user) %></url>
|
||||
<title><%= @user.nickname <> "'s timeline" %></title>
|
||||
<link><%= "#{Routes.user_feed_url(@conn, :feed, @user.nickname)}.rss" %></link>
|
||||
</image>
|
||||
<lastBuildDate><%= most_recent_update(@activities, @user, :rss) %></lastBuildDate>
|
||||
<webfeeds:icon><%= logo(@user) %></webfeeds:icon>
|
||||
<generator><%= Pleroma.Application.named_version() %></generator>
|
||||
|
||||
<%= render Phoenix.Controller.view_module(@conn), "_author.rss", assigns %>
|
||||
|
||||
<%= if last_activity(@activities) do %>
|
||||
<link rel="next"><%= "#{Routes.user_feed_url(@conn, :feed, @user.nickname)}.rss?max_id=#{last_activity(@activities).id}" %></link>
|
||||
<atom:link rel="next" href="<%= "#{Routes.user_feed_url(@conn, :feed, @user.nickname)}.rss?max_id=#{last_activity(@activities).id}" %>" />
|
||||
<% end %>
|
||||
|
||||
<%= for activity <- @activities do %>
|
||||
|
|
|
|||
|
|
@ -4,25 +4,39 @@
|
|||
|
||||
defmodule Pleroma.Workers.PublisherWorker do
|
||||
alias Pleroma.Activity
|
||||
alias Pleroma.Config
|
||||
alias Pleroma.Instances
|
||||
alias Pleroma.Web.Federator
|
||||
|
||||
use Oban.Worker, queue: :federator_outgoing, max_attempts: 13
|
||||
|
||||
@publish_one_param_keys %{
|
||||
"activity_id" => :activity_id,
|
||||
"cc" => :cc,
|
||||
"inbox" => :inbox,
|
||||
"unreachable_since" => :unreachable_since
|
||||
}
|
||||
|
||||
@impl true
|
||||
def perform(%Job{args: %{"op" => "publish", "activity_id" => activity_id}}) do
|
||||
activity = Activity.get_by_id(activity_id)
|
||||
Federator.perform(:publish, activity)
|
||||
federator().perform(:publish, activity)
|
||||
end
|
||||
|
||||
def perform(%Job{args: %{"op" => "publish_one", "params" => params}} = job) do
|
||||
params = Map.new(params, fn {k, v} -> {String.to_atom(k), v} end)
|
||||
params =
|
||||
Enum.reduce(params, %{}, fn {key, value}, acc ->
|
||||
case @publish_one_param_keys do
|
||||
%{^key => atom_key} -> Map.put(acc, atom_key, value)
|
||||
_ -> acc
|
||||
end
|
||||
end)
|
||||
|
||||
# Cancel / skip the job if this server believed to be unreachable now
|
||||
if not Instances.reachable?(params.inbox) do
|
||||
{:cancel, :unreachable}
|
||||
else
|
||||
case Federator.perform(:publish_one, params) do
|
||||
case federator().perform(:publish_one, params) do
|
||||
{:ok, _} ->
|
||||
:ok
|
||||
|
||||
|
|
@ -44,6 +58,8 @@ defmodule Pleroma.Workers.PublisherWorker do
|
|||
@impl true
|
||||
def timeout(_job), do: :timer.seconds(10)
|
||||
|
||||
defp federator, do: Config.get([:pipeline, :federator], Federator)
|
||||
|
||||
@base_backoff 15
|
||||
@pow 5
|
||||
@impl true
|
||||
|
|
|
|||
7
mix.exs
7
mix.exs
|
|
@ -15,6 +15,13 @@ defmodule Pleroma.Mixfile do
|
|||
aliases: aliases(),
|
||||
deps: deps(),
|
||||
test_coverage: [tool: :covertool, summary: true],
|
||||
test_ignore_filters: [
|
||||
"test/credo/check/consistency/file_location.ex",
|
||||
"test/fixtures/config/temp.exported_from_db.secret.exs",
|
||||
"test/fixtures/config/temp.secret.exs",
|
||||
"test/fixtures/modules/good_mrf.ex",
|
||||
"test/fixtures/modules/runtime_module.ex"
|
||||
],
|
||||
# Docs
|
||||
name: "Pleroma",
|
||||
homepage_url: "https://pleroma.social/",
|
||||
|
|
|
|||
|
|
@ -369,5 +369,39 @@ defmodule Mix.Tasks.Pleroma.ConfigTest do
|
|||
MixTask.run(["filter_whitelisted", "--force"])
|
||||
assert config_records() == existing
|
||||
end
|
||||
|
||||
test "filters blacklisted settings" do
|
||||
clear_config(:database_config_whitelist, [{:pleroma}])
|
||||
clear_config(:database_config_blacklist, [{:pleroma, :logger}, {:blacklisted_group}])
|
||||
|
||||
insert_config_record(:pleroma, :logger, backends: :console)
|
||||
insert_config_record(:web_push_encryption, :vapid_details, a: 1)
|
||||
insert_config_record(:blacklisted_group, :anything, a: 1)
|
||||
|
||||
MixTask.run(["filter_blacklisted", "--force"])
|
||||
|
||||
assert [
|
||||
%ConfigDB{group: :pleroma, key: :instance},
|
||||
%ConfigDB{group: :pleroma, key: Pleroma.Captcha},
|
||||
%ConfigDB{group: :pleroma2, key: :key2},
|
||||
%ConfigDB{group: :web_push_encryption, key: :vapid_details}
|
||||
] = config_records()
|
||||
end
|
||||
|
||||
test "filter_blacklisted doesn't crash when blacklist is unset" do
|
||||
clear_config(:database_config_blacklist, nil)
|
||||
|
||||
existing = config_records()
|
||||
MixTask.run(["filter_blacklisted", "--force"])
|
||||
assert config_records() == existing
|
||||
end
|
||||
|
||||
test "filter_blacklisted doesn't crash when blacklist is disabled" do
|
||||
clear_config(:database_config_blacklist, false)
|
||||
|
||||
existing = config_records()
|
||||
MixTask.run(["filter_blacklisted", "--force"])
|
||||
assert config_records() == existing
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
39
test/pleroma/application_test.exs
Normal file
39
test/pleroma/application_test.exs
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2026 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.ApplicationTest do
|
||||
use Pleroma.DataCase
|
||||
|
||||
import ExUnit.CaptureLog
|
||||
|
||||
# TODO HACK: Temporarily disabled.
|
||||
# Currently causes a bunch of warnings about :warn being deprecated in logs.
|
||||
# ex_syslogger needs to either be updated upstream or forked.
|
||||
describe "config :pleroma, :logger, backends: [{:ex_syslogger, :ex_syslogger}]" do
|
||||
setup do
|
||||
clear_config([:logger], backends: [{:ex_syslogger, :ex_syslogger}])
|
||||
end
|
||||
|
||||
@tag :skip
|
||||
test "is handled" do
|
||||
log = capture_log(fn -> Pleroma.Application.configure_logger() end)
|
||||
|
||||
assert log =~
|
||||
"Configuration {:ex_syslogger, :ex_syslogger} is incorrect. Use {ExSyslogger, :ex_syslogger} instead!"
|
||||
|
||||
assert log =~ "Successfully added logger backend: {ExSyslogger, :ex_syslogger}"
|
||||
end
|
||||
end
|
||||
|
||||
describe "config :pleroma, :logger, :backends: [:console]" do
|
||||
setup do
|
||||
clear_config([:logger], backends: [:console])
|
||||
end
|
||||
|
||||
test "emits a warning" do
|
||||
assert capture_log(fn -> Pleroma.Application.configure_logger() end) =~
|
||||
":console is no longer considered a backend and is enabled by default"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Config.DeprecationWarningsTest do
|
||||
use ExUnit.Case
|
||||
use ExUnit.Case, async: false
|
||||
use Pleroma.Tests.Helpers
|
||||
|
||||
import ExUnit.CaptureLog
|
||||
|
|
@ -388,4 +388,62 @@ defmodule Pleroma.Config.DeprecationWarningsTest do
|
|||
end) =~
|
||||
"Your config is using the old namespace for the Shoutbox configuration."
|
||||
end
|
||||
|
||||
describe "check_deprecated_logger_config" do
|
||||
setup do
|
||||
initial_console = Application.get_env(:logger, :console, nil)
|
||||
initial_backends = Application.get_env(:logger, :backends, nil)
|
||||
|
||||
# NOTE: The Logger does not get reconfigured when running in the test env,
|
||||
# the added and on_exit removed settings below should have no effect besides
|
||||
# triggering the deprecation warnings
|
||||
Application.put_env(:logger, :console, level: :all)
|
||||
Application.put_env(:logger, :backends, [:console])
|
||||
|
||||
on_exit(fn ->
|
||||
if initial_console do
|
||||
Application.put_env(:logger, :console, initial_console)
|
||||
else
|
||||
Application.delete_env(:logger, :console)
|
||||
end
|
||||
|
||||
if initial_backends do
|
||||
Application.put_env(:logger, :backends, initial_backends)
|
||||
else
|
||||
Application.delete_env(:logger, :backends)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
test "warns on deprecated syntax" do
|
||||
log =
|
||||
capture_log(fn ->
|
||||
Pleroma.Config.DeprecationWarnings.check_deprecated_logger_config()
|
||||
end)
|
||||
|
||||
assert log =~
|
||||
"""
|
||||
!!!DEPRECATION WARNING!!!
|
||||
Your configuration is using deprecated syntax for configuring backends of Elixir's logger.
|
||||
`config :logger, backends: [...]` is deprecated syntax due to changes in Elixir.
|
||||
Please update your configuration at your earliest convenience to use:
|
||||
`config :pleroma, :logger, backends: [...]`
|
||||
|
||||
Note: `:console` is no longer considered a backend and is used by default, you can disable it using:
|
||||
`config :logger, :default_handler: false`
|
||||
"""
|
||||
|
||||
assert log =~
|
||||
"""
|
||||
!!!DEPRECATION WARNING!!!
|
||||
Your configuration is using deprecated syntax for configuring logging to console.
|
||||
`config :logger, :console` is deprecated syntax due to changes in Elixir.
|
||||
Please update your configuration at your earliest convenience to use
|
||||
`config :logger, default_handler` and `config :logger, :default_formatter`.
|
||||
|
||||
Note: `:default_handler` is used only for the `level` setting. All other configurations go under
|
||||
`:default_formatter`. For more info visit: https://hexdocs.pm/logger/Logger.html#module-backends-and-backwards-compatibility
|
||||
"""
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue