diff options
author | Roman Chvanikov <chvanikoff@pm.me> | 2020-06-23 20:55:14 +0300 |
---|---|---|
committer | Roman Chvanikov <chvanikoff@pm.me> | 2020-06-23 20:55:14 +0300 |
commit | ccf5442d1467b080d1e52f5180b4e22db51caf12 (patch) | |
tree | 30d92236e03c04a5cda1c1f5d0a0f584c1757f28 /lib | |
parent | 7a56664ffad9869540e2d68a4130454b92d2156f (diff) | |
parent | c7d69e925664ce7125c3938c298d72e94a2a1349 (diff) | |
download | pleroma-ccf5442d1467b080d1e52f5180b4e22db51caf12.tar.gz |
Merge develop
Diffstat (limited to 'lib')
-rw-r--r-- | lib/mix/tasks/pleroma/config.ex | 1 | ||||
-rw-r--r-- | lib/pleroma/application.ex | 2 | ||||
-rw-r--r-- | lib/pleroma/application_requirements.ex | 107 | ||||
-rw-r--r-- | lib/pleroma/config/config_db.ex | 4 | ||||
-rw-r--r-- | lib/pleroma/config/deprecation_warnings.ex | 44 | ||||
-rw-r--r-- | lib/pleroma/repo.ex | 37 | ||||
-rw-r--r-- | lib/pleroma/web/activity_pub/activity_pub_controller.ex | 3 | ||||
-rw-r--r-- | lib/pleroma/web/activity_pub/mrf.ex | 4 | ||||
-rw-r--r-- | lib/pleroma/web/activity_pub/mrf/simple_policy.ex | 28 | ||||
-rw-r--r-- | lib/pleroma/web/api_spec/operations/notification_operation.ex | 10 | ||||
-rw-r--r-- | lib/pleroma/web/masto_fe_controller.ex | 2 | ||||
-rw-r--r-- | lib/pleroma/web/mastodon_api/views/instance_view.ex | 9 | ||||
-rw-r--r-- | lib/pleroma/web/mastodon_api/views/notification_view.ex | 8 | ||||
-rw-r--r-- | lib/pleroma/web/router.ex | 2 |
14 files changed, 192 insertions, 69 deletions
diff --git a/lib/mix/tasks/pleroma/config.ex b/lib/mix/tasks/pleroma/config.ex index f1b3a8766..d5129d410 100644 --- a/lib/mix/tasks/pleroma/config.ex +++ b/lib/mix/tasks/pleroma/config.ex @@ -52,6 +52,7 @@ defmodule Mix.Tasks.Pleroma.Config do defp do_migrate_to_db(config_file) do if File.exists?(config_file) do + shell_info("Migrating settings from file: #{Path.expand(config_file)}") Ecto.Adapters.SQL.query!(Repo, "TRUNCATE config;") Ecto.Adapters.SQL.query!(Repo, "ALTER SEQUENCE config_id_seq RESTART;") diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex index 521052817..293a16483 100644 --- a/lib/pleroma/application.ex +++ b/lib/pleroma/application.ex @@ -41,7 +41,7 @@ defmodule Pleroma.Application do Pleroma.HTML.compile_scrubbers() Config.DeprecationWarnings.warn() Pleroma.Plugs.HTTPSecurityPlug.warn_if_disabled() - Pleroma.Repo.check_migrations_applied!() + Pleroma.ApplicationRequirements.verify!() setup_instrumenters() load_custom_modules() diff --git a/lib/pleroma/application_requirements.ex b/lib/pleroma/application_requirements.ex new file mode 100644 index 000000000..88575a498 --- /dev/null +++ b/lib/pleroma/application_requirements.ex @@ -0,0 +1,107 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.ApplicationRequirements do + @moduledoc """ + The module represents the collection of validations to runs before start server. + """ + + defmodule VerifyError, do: defexception([:message]) + + import Ecto.Query + + require Logger + + @spec verify!() :: :ok | VerifyError.t() + def verify! do + :ok + |> check_migrations_applied!() + |> check_rum!() + |> handle_result() + end + + defp handle_result(:ok), do: :ok + defp handle_result({:error, message}), do: raise(VerifyError, message: message) + + # Checks for pending migrations. + # + def check_migrations_applied!(:ok) do + unless Pleroma.Config.get( + [:i_am_aware_this_may_cause_data_loss, :disable_migration_check], + false + ) do + {_, res, _} = + Ecto.Migrator.with_repo(Pleroma.Repo, fn repo -> + down_migrations = + Ecto.Migrator.migrations(repo) + |> Enum.reject(fn + {:up, _, _} -> true + {:down, _, _} -> false + end) + + if length(down_migrations) > 0 do + down_migrations_text = + Enum.map(down_migrations, fn {:down, id, name} -> "- #{name} (#{id})\n" end) + + Logger.error( + "The following migrations were not applied:\n#{down_migrations_text}If you want to start Pleroma anyway, set\nconfig :pleroma, :i_am_aware_this_may_cause_data_loss, disable_migration_check: true" + ) + + {:error, "Unapplied Migrations detected"} + else + :ok + end + end) + + res + else + :ok + end + end + + def check_migrations_applied!(result), do: result + + # Checks for settings of RUM indexes. + # + defp check_rum!(:ok) do + {_, res, _} = + Ecto.Migrator.with_repo(Pleroma.Repo, fn repo -> + migrate = + from(o in "columns", + where: o.table_name == "objects", + where: o.column_name == "fts_content" + ) + |> repo.exists?(prefix: "information_schema") + + setting = Pleroma.Config.get([:database, :rum_enabled], false) + + do_check_rum!(setting, migrate) + end) + + res + end + + defp check_rum!(result), do: result + + defp do_check_rum!(setting, migrate) do + case {setting, migrate} do + {true, false} -> + Logger.error( + "Use `RUM` index is enabled, but were not applied migrations for it.\nIf you want to start Pleroma anyway, set\nconfig :pleroma, :database, rum_enabled: false\nOtherwise apply the following migrations:\n`mix ecto.migrate --migrations-path priv/repo/optional_migrations/rum_indexing/`" + ) + + {:error, "Unapplied RUM Migrations detected"} + + {false, true} -> + Logger.error( + "Detected applied migrations to use `RUM` index, but `RUM` isn't enable in settings.\nIf you want to use `RUM`, set\nconfig :pleroma, :database, rum_enabled: true\nOtherwise roll `RUM` migrations back.\n`mix ecto.rollback --migrations-path priv/repo/optional_migrations/rum_indexing/`" + ) + + {:error, "RUM Migrations detected"} + + _ -> + :ok + end + end +end diff --git a/lib/pleroma/config/config_db.ex b/lib/pleroma/config/config_db.ex index 2f4eb8581..1a89d8895 100644 --- a/lib/pleroma/config/config_db.ex +++ b/lib/pleroma/config/config_db.ex @@ -167,7 +167,9 @@ defmodule Pleroma.ConfigDB do end) end - @spec delete(map()) :: {:ok, ConfigDB.t()} | {:error, Changeset.t()} + @spec delete(ConfigDB.t() | map()) :: {:ok, ConfigDB.t()} | {:error, Changeset.t()} + def delete(%ConfigDB{} = config), do: Repo.delete(config) + def delete(params) do search_opts = Map.delete(params, :subkeys) diff --git a/lib/pleroma/config/deprecation_warnings.ex b/lib/pleroma/config/deprecation_warnings.ex index b68ded01f..0a6c724fb 100644 --- a/lib/pleroma/config/deprecation_warnings.ex +++ b/lib/pleroma/config/deprecation_warnings.ex @@ -3,9 +3,23 @@ # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Config.DeprecationWarnings do + alias Pleroma.Config + require Logger alias Pleroma.Config + @type config_namespace() :: [atom()] + @type config_map() :: {config_namespace(), config_namespace(), String.t()} + + @mrf_config_map [ + {[:instance, :rewrite_policy], [:mrf, :policies], + "\n* `config :pleroma, :instance, rewrite_policy` is now `config :pleroma, :mrf, policies`"}, + {[:instance, :mrf_transparency], [:mrf, :transparency], + "\n* `config :pleroma, :instance, mrf_transparency` is now `config :pleroma, :mrf, transparency`"}, + {[:instance, :mrf_transparency_exclusions], [:mrf, :transparency_exclusions], + "\n* `config :pleroma, :instance, mrf_transparency_exclusions` is now `config :pleroma, :mrf, transparency_exclusions`"} + ] + def check_hellthread_threshold do if Config.get([:mrf_hellthread, :threshold]) do Logger.warn(""" @@ -39,5 +53,35 @@ defmodule Pleroma.Config.DeprecationWarnings do def warn do check_hellthread_threshold() mrf_user_allowlist() + check_old_mrf_config() + end + + def check_old_mrf_config do + warning_preface = """ + !!!DEPRECATION WARNING!!! + Your config is using old namespaces for MRF configuration. They should work for now, but you are advised to change to new namespaces to prevent possible issues later: + """ + + move_namespace_and_warn(@mrf_config_map, warning_preface) + end + + @spec move_namespace_and_warn([config_map()], String.t()) :: :ok + def move_namespace_and_warn(config_map, warning_preface) do + warning = + Enum.reduce(config_map, "", fn + {old, new, err_msg}, acc -> + old_config = Config.get(old) + + if old_config do + Config.put(new, old_config) + acc <> err_msg + else + acc + end + end) + + if warning != "" do + Logger.warn(warning_preface <> warning) + end end end diff --git a/lib/pleroma/repo.ex b/lib/pleroma/repo.ex index 6d85d70bc..f317e4d58 100644 --- a/lib/pleroma/repo.ex +++ b/lib/pleroma/repo.ex @@ -11,9 +11,7 @@ defmodule Pleroma.Repo do import Ecto.Query require Logger - defmodule Instrumenter do - use Prometheus.EctoInstrumenter - end + defmodule Instrumenter, do: use(Prometheus.EctoInstrumenter) @doc """ Dynamically loads the repository url from the @@ -51,35 +49,6 @@ defmodule Pleroma.Repo do end end - def check_migrations_applied!() do - unless Pleroma.Config.get( - [:i_am_aware_this_may_cause_data_loss, :disable_migration_check], - false - ) do - Ecto.Migrator.with_repo(__MODULE__, fn repo -> - down_migrations = - Ecto.Migrator.migrations(repo) - |> Enum.reject(fn - {:up, _, _} -> true - {:down, _, _} -> false - end) - - if length(down_migrations) > 0 do - down_migrations_text = - Enum.map(down_migrations, fn {:down, id, name} -> "- #{name} (#{id})\n" end) - - Logger.error( - "The following migrations were not applied:\n#{down_migrations_text}If you want to start Pleroma anyway, set\nconfig :pleroma, :i_am_aware_this_may_cause_data_loss, disable_migration_check: true" - ) - - raise Pleroma.Repo.UnappliedMigrationsError - end - end) - else - :ok - end - end - def chunk_stream(query, chunk_size) do # We don't actually need start and end funcitons of resource streaming, # but it seems to be the only way to not fetch records one-by-one and @@ -107,7 +76,3 @@ defmodule Pleroma.Repo do ) end end - -defmodule Pleroma.Repo.UnappliedMigrationsError do - defexception message: "Unapplied Migrations detected" -end diff --git a/lib/pleroma/web/activity_pub/activity_pub_controller.ex b/lib/pleroma/web/activity_pub/activity_pub_controller.ex index f0b5c6e93..220c4fe52 100644 --- a/lib/pleroma/web/activity_pub/activity_pub_controller.ex +++ b/lib/pleroma/web/activity_pub/activity_pub_controller.ex @@ -514,7 +514,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do {new_user, for_user} end - # TODO: Add support for "object" field @doc """ Endpoint based on <https://www.w3.org/wiki/SocialCG/ActivityPub/MediaUpload> @@ -525,6 +524,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do Response: - HTTP Code: 201 Created - HTTP Body: ActivityPub object to be inserted into another's `attachment` field + + Note: Will not point to a URL with a `Location` header because no standalone Activity has been created. """ def upload_media(%{assigns: %{user: %User{} = user}} = conn, %{"file" => file} = data) do with {:ok, object} <- diff --git a/lib/pleroma/web/activity_pub/mrf.ex b/lib/pleroma/web/activity_pub/mrf.ex index 5a4a76085..206d6af52 100644 --- a/lib/pleroma/web/activity_pub/mrf.ex +++ b/lib/pleroma/web/activity_pub/mrf.ex @@ -16,7 +16,7 @@ defmodule Pleroma.Web.ActivityPub.MRF do def filter(%{} = object), do: get_policies() |> filter(object) def get_policies do - Pleroma.Config.get([:instance, :rewrite_policy], []) |> get_policies() + Pleroma.Config.get([:mrf, :policies], []) |> get_policies() end defp get_policies(policy) when is_atom(policy), do: [policy] @@ -51,7 +51,7 @@ defmodule Pleroma.Web.ActivityPub.MRF do get_policies() |> Enum.map(fn policy -> to_string(policy) |> String.split(".") |> List.last() end) - exclusions = Pleroma.Config.get([:instance, :mrf_transparency_exclusions]) + exclusions = Pleroma.Config.get([:mrf, :transparency_exclusions]) base = %{ diff --git a/lib/pleroma/web/activity_pub/mrf/simple_policy.ex b/lib/pleroma/web/activity_pub/mrf/simple_policy.ex index b7dcb1b86..9cea6bcf9 100644 --- a/lib/pleroma/web/activity_pub/mrf/simple_policy.ex +++ b/lib/pleroma/web/activity_pub/mrf/simple_policy.ex @@ -3,21 +3,23 @@ # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do - alias Pleroma.User - alias Pleroma.Web.ActivityPub.MRF @moduledoc "Filter activities depending on their origin instance" @behaviour Pleroma.Web.ActivityPub.MRF + alias Pleroma.Config + alias Pleroma.User + alias Pleroma.Web.ActivityPub.MRF + require Pleroma.Constants defp check_accept(%{host: actor_host} = _actor_info, object) do accepts = - Pleroma.Config.get([:mrf_simple, :accept]) + Config.get([:mrf_simple, :accept]) |> MRF.subdomains_regex() cond do accepts == [] -> {:ok, object} - actor_host == Pleroma.Config.get([Pleroma.Web.Endpoint, :url, :host]) -> {:ok, object} + actor_host == Config.get([Pleroma.Web.Endpoint, :url, :host]) -> {:ok, object} MRF.subdomain_match?(accepts, actor_host) -> {:ok, object} true -> {:reject, nil} end @@ -25,7 +27,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do defp check_reject(%{host: actor_host} = _actor_info, object) do rejects = - Pleroma.Config.get([:mrf_simple, :reject]) + Config.get([:mrf_simple, :reject]) |> MRF.subdomains_regex() if MRF.subdomain_match?(rejects, actor_host) do @@ -41,7 +43,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do ) when length(child_attachment) > 0 do media_removal = - Pleroma.Config.get([:mrf_simple, :media_removal]) + Config.get([:mrf_simple, :media_removal]) |> MRF.subdomains_regex() object = @@ -65,7 +67,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do } = object ) do media_nsfw = - Pleroma.Config.get([:mrf_simple, :media_nsfw]) + Config.get([:mrf_simple, :media_nsfw]) |> MRF.subdomains_regex() object = @@ -85,7 +87,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do defp check_ftl_removal(%{host: actor_host} = _actor_info, object) do timeline_removal = - Pleroma.Config.get([:mrf_simple, :federated_timeline_removal]) + Config.get([:mrf_simple, :federated_timeline_removal]) |> MRF.subdomains_regex() object = @@ -108,7 +110,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do defp check_report_removal(%{host: actor_host} = _actor_info, %{"type" => "Flag"} = object) do report_removal = - Pleroma.Config.get([:mrf_simple, :report_removal]) + Config.get([:mrf_simple, :report_removal]) |> MRF.subdomains_regex() if MRF.subdomain_match?(report_removal, actor_host) do @@ -122,7 +124,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do defp check_avatar_removal(%{host: actor_host} = _actor_info, %{"icon" => _icon} = object) do avatar_removal = - Pleroma.Config.get([:mrf_simple, :avatar_removal]) + Config.get([:mrf_simple, :avatar_removal]) |> MRF.subdomains_regex() if MRF.subdomain_match?(avatar_removal, actor_host) do @@ -136,7 +138,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do defp check_banner_removal(%{host: actor_host} = _actor_info, %{"image" => _image} = object) do banner_removal = - Pleroma.Config.get([:mrf_simple, :banner_removal]) + Config.get([:mrf_simple, :banner_removal]) |> MRF.subdomains_regex() if MRF.subdomain_match?(banner_removal, actor_host) do @@ -197,10 +199,10 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do @impl true def describe do - exclusions = Pleroma.Config.get([:instance, :mrf_transparency_exclusions]) + exclusions = Config.get([:mrf, :transparency_exclusions]) mrf_simple = - Pleroma.Config.get(:mrf_simple) + Config.get(:mrf_simple) |> Enum.map(fn {k, v} -> {k, Enum.reject(v, fn v -> v in exclusions end)} end) |> Enum.into(%{}) diff --git a/lib/pleroma/web/api_spec/operations/notification_operation.ex b/lib/pleroma/web/api_spec/operations/notification_operation.ex index 41328b5f2..f09be64cb 100644 --- a/lib/pleroma/web/api_spec/operations/notification_operation.ex +++ b/lib/pleroma/web/api_spec/operations/notification_operation.ex @@ -163,6 +163,13 @@ defmodule Pleroma.Web.ApiSpec.NotificationOperation do description: "Status that was the object of the notification, e.g. in mentions, reblogs, favourites, or polls.", nullable: true + }, + pleroma: %Schema{ + type: :object, + properties: %{ + is_seen: %Schema{type: :boolean}, + is_muted: %Schema{type: :boolean} + } } }, example: %{ @@ -170,7 +177,8 @@ defmodule Pleroma.Web.ApiSpec.NotificationOperation do "type" => "mention", "created_at" => "2019-11-23T07:49:02.064Z", "account" => Account.schema().example, - "status" => Status.schema().example + "status" => Status.schema().example, + "pleroma" => %{"is_seen" => false, "is_muted" => false} } } end diff --git a/lib/pleroma/web/masto_fe_controller.ex b/lib/pleroma/web/masto_fe_controller.ex index d0d8bc8eb..43ec70021 100644 --- a/lib/pleroma/web/masto_fe_controller.ex +++ b/lib/pleroma/web/masto_fe_controller.ex @@ -49,7 +49,7 @@ defmodule Pleroma.Web.MastoFEController do |> render("manifest.json") end - @doc "PUT /api/web/settings" + @doc "PUT /api/web/settings: Backend-obscure settings blob for MastoFE, don't parse/reuse elsewhere" def put_settings(%{assigns: %{user: user}} = conn, %{"data" => settings} = _params) do with {:ok, _} <- User.mastodon_settings_update(user, settings) do json(conn, %{}) diff --git a/lib/pleroma/web/mastodon_api/views/instance_view.ex b/lib/pleroma/web/mastodon_api/views/instance_view.ex index c498fe632..35c2fc25c 100644 --- a/lib/pleroma/web/mastodon_api/views/instance_view.ex +++ b/lib/pleroma/web/mastodon_api/views/instance_view.ex @@ -23,7 +23,7 @@ defmodule Pleroma.Web.MastodonAPI.InstanceView do streaming_api: Pleroma.Web.Endpoint.websocket_url() }, stats: Pleroma.Stats.get_stats(), - thumbnail: instance_thumbnail(), + thumbnail: Keyword.get(instance, :instance_thumbnail), languages: ["en"], registrations: Keyword.get(instance, :registrations_open), # Extra (not present in Mastodon): @@ -78,7 +78,7 @@ defmodule Pleroma.Web.MastodonAPI.InstanceView do def federation do quarantined = Config.get([:instance, :quarantined_instances], []) - if Config.get([:instance, :mrf_transparency]) do + if Config.get([:mrf, :transparency]) do {:ok, data} = MRF.describe() data @@ -88,9 +88,4 @@ defmodule Pleroma.Web.MastodonAPI.InstanceView do end |> Map.put(:enabled, Config.get([:instance, :federating])) end - - defp instance_thumbnail do - Pleroma.Config.get([:instance, :instance_thumbnail]) || - "#{Pleroma.Web.base_url()}/instance/thumbnail.jpeg" - end end diff --git a/lib/pleroma/web/mastodon_api/views/notification_view.ex b/lib/pleroma/web/mastodon_api/views/notification_view.ex index 3865be280..c97e6d32f 100644 --- a/lib/pleroma/web/mastodon_api/views/notification_view.ex +++ b/lib/pleroma/web/mastodon_api/views/notification_view.ex @@ -84,12 +84,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationView do # Note: :relationships contain user mutes (needed for :muted flag in :status) status_render_opts = %{relationships: opts[:relationships]} - - account = - AccountView.render( - "show.json", - %{user: actor, for: reading_user} - ) + account = AccountView.render("show.json", %{user: actor, for: reading_user}) response = %{ id: to_string(notification.id), @@ -97,6 +92,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationView do created_at: CommonAPI.Utils.to_masto_date(notification.inserted_at), account: account, pleroma: %{ + is_muted: User.mutes?(reading_user, actor), is_seen: notification.seen } } diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index 25a67cdcb..c837e83fe 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -467,6 +467,8 @@ defmodule Pleroma.Web.Router do scope "/api/web", Pleroma.Web do pipe_through(:authenticated_api) + # Backend-obscure settings blob for MastoFE, don't parse/reuse elsewhere + # put("/settings", MastoFEController, :put_settings) put("/settings", FrontendController, :put_settings, as: :frontend_mastodon) end |