logo

pleroma

My custom branche(s) on git.pleroma.social/pleroma/pleroma
commit: c51e93978ea2aa0f2d5bcc43bf7c925b2590eece
parent: 7447c80e33a7d54c3d9f03f5c0be3fb738f1318b
Author: rinpatch <rinpatch@sdf.org>
Date:   Sat, 21 Dec 2019 11:56:24 +0000

Merge branch 'feature/custom-runtime-modules' into 'develop'

Add support for custom modules at runtime

Closes #1448

See merge request pleroma/pleroma!2039

Diffstat:

MCHANGELOG.md2++
Mconfig/config.exs2++
Mconfig/prod.exs4++--
Mconfig/releases.exs1+
Mconfig/test.exs2++
Mdocs/configuration/cheatsheet.md4++++
Mlib/pleroma/application.ex24++++++++++++++++++++++++
Mlib/pleroma/html.ex4+---
Mlib/pleroma/object/fetcher.ex2+-
Alib/pleroma/utils.ex12++++++++++++
Mlib/pleroma/web/activity_pub/activity_pub_controller.ex6+++---
Mlib/pleroma/web/activity_pub/mrf/drop_policy.ex2+-
Mlib/pleroma/web/activity_pub/mrf/mediaproxy_warming_policy.ex2+-
Mlib/pleroma/web/activity_pub/publisher.ex4++--
Mlib/pleroma/web/endpoint.ex2+-
Mlib/pleroma/web/federator/federator.ex8++++----
Mlib/pleroma/web/federator/publisher.ex2+-
Atest/fixtures/modules/runtime_module.ex9+++++++++
Atest/runtime_test.exs11+++++++++++
19 files changed, 84 insertions(+), 19 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md @@ -21,6 +21,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Deprecated `User.Info` embedded schema (fields moved to `User`) - Store status data inside Flag activity - Deprecated (reorganized as `UserRelationship` entity) User fields with user AP IDs (`blocks`, `mutes`, `muted_reblogs`, `muted_notifications`, `subscribers`). +- Logger: default log level changed from `warn` to `info`. <details> <summary>API Changes</summary> @@ -51,6 +52,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Support for `X-Forwarded-For` and similar HTTP headers which used by reverse proxies to pass a real user IP address to the backend. Must not be enabled unless your instance is behind at least one reverse proxy (such as Nginx, Apache HTTPD or Varnish Cache). - MRF: New module which handles incoming posts based on their age. By default, all incoming posts that are older than 2 days will be unlisted and not shown to their followers. - User notification settings: Add `privacy_option` option. +- Support for custom Elixir modules (such as MRF policies) - User settings: Add _This account is a_ option. - OAuth: admin scopes support (relevant setting: `[:auth, :enforce_oauth_admin_scope_usage]`). <details> diff --git a/config/config.exs b/config/config.exs @@ -621,6 +621,8 @@ config :pleroma, :web_cache_ttl, activity_pub: nil, activity_pub_question: 30_000 +config :pleroma, :modules, runtime_dir: "instance/modules" + config :swarm, node_blacklist: [~r/myhtml_.*$/] # Import environment specific config. This must remain at the bottom # of this file so it overrides the configuration defined above. diff --git a/config/prod.exs b/config/prod.exs @@ -20,8 +20,8 @@ config :pleroma, Pleroma.Web.Endpoint, config :phoenix, serve_endpoints: true # Do not print debug messages in production -config :logger, :console, level: :warn -config :logger, :ex_syslogger, level: :warn +config :logger, :console, level: :info +config :logger, :ex_syslogger, level: :info # ## SSL Support # diff --git a/config/releases.exs b/config/releases.exs @@ -2,6 +2,7 @@ import Config config :pleroma, :instance, static_dir: "/var/lib/pleroma/static" config :pleroma, Pleroma.Uploaders.Local, uploads: "/var/lib/pleroma/uploads" +config :pleroma, :modules, runtime_dir: "/var/lib/pleroma/modules" config_path = System.get_env("PLEROMA_CONFIG_PATH") || "/etc/pleroma/config.exs" diff --git a/config/test.exs b/config/test.exs @@ -95,6 +95,8 @@ config :joken, default_signer: "yU8uHKq+yyAkZ11Hx//jcdacWc8yQ1bxAAGrplzB0Zwwjkp3 config :pleroma, Pleroma.ReverseProxy.Client, Pleroma.ReverseProxy.ClientMock +config :pleroma, :modules, runtime_dir: "test/fixtures/modules" + if File.exists?("./config/test.secret.exs") do import_config "test.secret.exs" else diff --git a/docs/configuration/cheatsheet.md b/docs/configuration/cheatsheet.md @@ -836,3 +836,7 @@ config :auto_linker, rel: "ugc" ] ``` + +## Custom Runtime Modules (`:modules`) + +* `runtime_dir`: A path to custom Elixir modules (such as MRF policies). diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex @@ -5,6 +5,7 @@ defmodule Pleroma.Application do import Cachex.Spec use Application + require Logger @name Mix.Project.config()[:name] @version Mix.Project.config()[:version] @@ -33,6 +34,7 @@ defmodule Pleroma.Application do Pleroma.HTML.compile_scrubbers() Pleroma.Config.DeprecationWarnings.warn() setup_instrumenters() + load_custom_modules() # Define workers and child supervisors to be supervised children = @@ -68,6 +70,28 @@ defmodule Pleroma.Application do Supervisor.start_link(children, opts) end + def load_custom_modules do + dir = Pleroma.Config.get([:modules, :runtime_dir]) + + if dir && File.exists?(dir) do + dir + |> Pleroma.Utils.compile_dir() + |> case do + {:error, _errors, _warnings} -> + raise "Invalid custom modules" + + {:ok, modules, _warnings} -> + if @env != :test do + Enum.each(modules, fn mod -> + Logger.info("Custom module loaded: #{inspect(mod)}") + end) + end + + :ok + end + end + end + defp setup_instrumenters do require Prometheus.Registry diff --git a/lib/pleroma/html.ex b/lib/pleroma/html.ex @@ -10,9 +10,7 @@ defmodule Pleroma.HTML do dir = Path.join(:code.priv_dir(:pleroma), "scrubbers") dir - |> File.ls!() - |> Enum.map(&Path.join(dir, &1)) - |> Kernel.ParallelCompiler.compile() + |> Pleroma.Utils.compile_dir() |> case do {:error, _errors, _warnings} -> raise "Compiling scrubbers failed" diff --git a/lib/pleroma/object/fetcher.ex b/lib/pleroma/object/fetcher.ex @@ -154,7 +154,7 @@ defmodule Pleroma.Object.Fetcher do end def fetch_and_contain_remote_object_from_id(id) when is_binary(id) do - Logger.info("Fetching object #{id} via AP") + Logger.debug("Fetching object #{id} via AP") date = Pleroma.Signature.signed_date() diff --git a/lib/pleroma/utils.ex b/lib/pleroma/utils.ex @@ -0,0 +1,12 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Utils do + def compile_dir(dir) when is_binary(dir) do + dir + |> File.ls!() + |> Enum.map(&Path.join(dir, &1)) + |> Kernel.ParallelCompiler.compile() + end +end diff --git a/lib/pleroma/web/activity_pub/activity_pub_controller.ex b/lib/pleroma/web/activity_pub/activity_pub_controller.ex @@ -257,7 +257,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do # only accept relayed Creates def inbox(conn, %{"type" => "Create"} = params) do - Logger.info( + Logger.debug( "Signature missing or not from author, relayed Create message, fetching object from source" ) @@ -270,11 +270,11 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do headers = Enum.into(conn.req_headers, %{}) if String.contains?(headers["signature"], params["actor"]) do - Logger.info( + Logger.debug( "Signature validation error for: #{params["actor"]}, make sure you are forwarding the HTTP Host header!" ) - Logger.info(inspect(conn.req_headers)) + Logger.debug(inspect(conn.req_headers)) end json(conn, dgettext("errors", "error")) diff --git a/lib/pleroma/web/activity_pub/mrf/drop_policy.ex b/lib/pleroma/web/activity_pub/mrf/drop_policy.ex @@ -9,7 +9,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.DropPolicy do @impl true def filter(object) do - Logger.info("REJECTING #{inspect(object)}") + Logger.debug("REJECTING #{inspect(object)}") {:reject, object} end diff --git a/lib/pleroma/web/activity_pub/mrf/mediaproxy_warming_policy.ex b/lib/pleroma/web/activity_pub/mrf/mediaproxy_warming_policy.ex @@ -18,7 +18,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy do ] def perform(:prefetch, url) do - Logger.info("Prefetching #{inspect(url)}") + Logger.debug("Prefetching #{inspect(url)}") url |> MediaProxy.url() diff --git a/lib/pleroma/web/activity_pub/publisher.ex b/lib/pleroma/web/activity_pub/publisher.ex @@ -48,7 +48,7 @@ defmodule Pleroma.Web.ActivityPub.Publisher do * `id`: the ActivityStreams URI of the message """ def publish_one(%{inbox: inbox, json: json, actor: %User{} = actor, id: id} = params) do - Logger.info("Federating #{id} to #{inbox}") + Logger.debug("Federating #{id} to #{inbox}") %{host: host, path: path} = URI.parse(inbox) digest = "SHA-256=" <> (:crypto.hash(:sha256, json) |> Base.encode64()) @@ -228,7 +228,7 @@ defmodule Pleroma.Web.ActivityPub.Publisher do public = is_public?(activity) if public && Config.get([:instance, :allow_relay]) do - Logger.info(fn -> "Relaying #{activity.data["id"]} out" end) + Logger.debug(fn -> "Relaying #{activity.data["id"]} out" end) Relay.publish(activity) end diff --git a/lib/pleroma/web/endpoint.ex b/lib/pleroma/web/endpoint.ex @@ -59,7 +59,7 @@ defmodule Pleroma.Web.Endpoint do plug(Pleroma.Plugs.TrailingFormatPlug) plug(Plug.RequestId) - plug(Plug.Logger) + plug(Plug.Logger, log: :debug) plug(Pleroma.Plugs.Parsers) diff --git a/lib/pleroma/web/federator/federator.ex b/lib/pleroma/web/federator/federator.ex @@ -58,7 +58,7 @@ defmodule Pleroma.Web.Federator do end def perform(:incoming_ap_doc, params) do - Logger.info("Handling incoming AP activity") + Logger.debug("Handling incoming AP activity") params = Utils.normalize_params(params) @@ -71,13 +71,13 @@ defmodule Pleroma.Web.Federator do {:ok, activity} else %Activity{} -> - Logger.info("Already had #{params["id"]}") + Logger.debug("Already had #{params["id"]}") :error _e -> # Just drop those for now - Logger.info("Unhandled activity") - Logger.info(Jason.encode!(params, pretty: true)) + Logger.debug("Unhandled activity") + Logger.debug(Jason.encode!(params, pretty: true)) :error end end diff --git a/lib/pleroma/web/federator/publisher.ex b/lib/pleroma/web/federator/publisher.ex @@ -47,7 +47,7 @@ defmodule Pleroma.Web.Federator.Publisher do Config.get([:instance, :federation_publisher_modules]) |> Enum.each(fn module -> if module.is_representable?(activity) do - Logger.info("Publishing #{activity.data["id"]} using #{inspect(module)}") + Logger.debug("Publishing #{activity.data["id"]} using #{inspect(module)}") module.publish(user, activity) end end) diff --git a/test/fixtures/modules/runtime_module.ex b/test/fixtures/modules/runtime_module.ex @@ -0,0 +1,9 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule RuntimeModule do + @moduledoc """ + This is a dummy module to test custom runtime modules. + """ +end diff --git a/test/runtime_test.exs b/test/runtime_test.exs @@ -0,0 +1,11 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.RuntimeTest do + use ExUnit.Case, async: true + + test "it loads custom runtime modules" do + assert Code.ensure_compiled?(RuntimeModule) + end +end