From 48ae3c4347f68e20db7e3e67da32be2e70599fb3 Mon Sep 17 00:00:00 2001 From: Egor Kislitsyn Date: Thu, 5 Dec 2019 20:18:25 +0700 Subject: Add support for custom modules --- lib/pleroma/application.ex | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'lib') diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex index 9dbd1e26b..5b6e233a6 100644 --- a/lib/pleroma/application.ex +++ b/lib/pleroma/application.ex @@ -32,6 +32,7 @@ defmodule Pleroma.Application do def start(_type, _args) do Pleroma.Config.DeprecationWarnings.warn() setup_instrumenters() + load_custom_modules() # Define workers and child supervisors to be supervised children = @@ -67,6 +68,29 @@ defmodule Pleroma.Application do Supervisor.start_link(children, opts) end + def load_custom_modules() do + dir = Pleroma.Config.get([:instance, :custom_modules_dir]) + + if dir && File.exists?(dir) do + dir + |> File.ls!() + |> Enum.map(&Path.join(dir, &1)) + |> Kernel.ParallelCompiler.compile() + |> case do + {:error, _errors, _warnings} -> + raise "Invalid custom modules" + + {:ok, modules, _warnings} -> + Enum.each(modules, fn mod -> + name = mod |> Atom.to_string() |> String.trim_leading("Elixir.") + IO.puts("Custom module loaded: #{name}") + end) + + :ok + end + end + end + defp setup_instrumenters do require Prometheus.Registry -- cgit v1.2.3 From 1216b546c6bc0540e266fe0f05829f4f683b1ce9 Mon Sep 17 00:00:00 2001 From: Egor Kislitsyn Date: Thu, 5 Dec 2019 20:29:17 +0700 Subject: Fix credo warning --- lib/pleroma/application.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex index 5b6e233a6..73364f141 100644 --- a/lib/pleroma/application.ex +++ b/lib/pleroma/application.ex @@ -68,7 +68,7 @@ defmodule Pleroma.Application do Supervisor.start_link(children, opts) end - def load_custom_modules() do + def load_custom_modules do dir = Pleroma.Config.get([:instance, :custom_modules_dir]) if dir && File.exists?(dir) do -- cgit v1.2.3 From 157bceeda9124cea7ba69eaf6639ca52b3fac7c6 Mon Sep 17 00:00:00 2001 From: Egor Kislitsyn Date: Fri, 6 Dec 2019 15:04:46 +0700 Subject: Move runtime configuration from `:instance` to `:modules` --- lib/pleroma/application.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex index 73364f141..9d2f3f320 100644 --- a/lib/pleroma/application.ex +++ b/lib/pleroma/application.ex @@ -69,7 +69,7 @@ defmodule Pleroma.Application do end def load_custom_modules do - dir = Pleroma.Config.get([:instance, :custom_modules_dir]) + dir = Pleroma.Config.get([:modules, :runtime_dir]) if dir && File.exists?(dir) do dir -- cgit v1.2.3 From e4292cbfad47e59c76461fa201bab3e5f791962b Mon Sep 17 00:00:00 2001 From: Egor Kislitsyn Date: Fri, 6 Dec 2019 15:16:39 +0700 Subject: Use Kernel.inspect/2 to print loaded custom modules --- lib/pleroma/application.ex | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex index 9d2f3f320..17f6b9c80 100644 --- a/lib/pleroma/application.ex +++ b/lib/pleroma/application.ex @@ -82,8 +82,7 @@ defmodule Pleroma.Application do {:ok, modules, _warnings} -> Enum.each(modules, fn mod -> - name = mod |> Atom.to_string() |> String.trim_leading("Elixir.") - IO.puts("Custom module loaded: #{name}") + IO.puts("Custom module loaded: #{inspect(mod)}") end) :ok -- cgit v1.2.3 From a75d4a41e03979b4d1b9af5205e457d714ff76df Mon Sep 17 00:00:00 2001 From: Egor Kislitsyn Date: Fri, 6 Dec 2019 17:05:09 +0700 Subject: Add a test for custom runtime modules --- lib/pleroma/application.ex | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex index 17f6b9c80..82a005700 100644 --- a/lib/pleroma/application.ex +++ b/lib/pleroma/application.ex @@ -81,9 +81,11 @@ defmodule Pleroma.Application do raise "Invalid custom modules" {:ok, modules, _warnings} -> - Enum.each(modules, fn mod -> - IO.puts("Custom module loaded: #{inspect(mod)}") - end) + if @env != :test do + Enum.each(modules, fn mod -> + IO.puts("Custom module loaded: #{inspect(mod)}") + end) + end :ok end -- cgit v1.2.3 From 84f891ea3e31c936bc990a3c2310d539df62fc44 Mon Sep 17 00:00:00 2001 From: Egor Kislitsyn Date: Mon, 9 Dec 2019 18:23:07 +0700 Subject: Add Pleroma.Utils.compile_dir/1 --- lib/pleroma/application.ex | 4 +--- lib/pleroma/utils.ex | 12 ++++++++++++ 2 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 lib/pleroma/utils.ex (limited to 'lib') diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex index 82a005700..104620b37 100644 --- a/lib/pleroma/application.ex +++ b/lib/pleroma/application.ex @@ -73,9 +73,7 @@ defmodule Pleroma.Application do if dir && File.exists?(dir) do dir - |> File.ls!() - |> Enum.map(&Path.join(dir, &1)) - |> Kernel.ParallelCompiler.compile() + |> Pleroma.Utils.compile_dir() |> case do {:error, _errors, _warnings} -> raise "Invalid custom modules" diff --git a/lib/pleroma/utils.ex b/lib/pleroma/utils.ex new file mode 100644 index 000000000..8d36a0001 --- /dev/null +++ b/lib/pleroma/utils.ex @@ -0,0 +1,12 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2019 Pleroma Authors +# 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 -- cgit v1.2.3 From ed92784e7cfe60756733f518efce14253b1c78d6 Mon Sep 17 00:00:00 2001 From: Egor Kislitsyn Date: Mon, 9 Dec 2019 19:11:54 +0700 Subject: Set Logger level to :info in prod --- lib/pleroma/application.ex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex index 104620b37..f47cb0ce9 100644 --- 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] @@ -81,7 +82,7 @@ defmodule Pleroma.Application do {:ok, modules, _warnings} -> if @env != :test do Enum.each(modules, fn mod -> - IO.puts("Custom module loaded: #{inspect(mod)}") + Logger.info("Custom module loaded: #{inspect(mod)}") end) end -- cgit v1.2.3 From 78299ab18205b0bbaf521640e188a862ca27aa61 Mon Sep 17 00:00:00 2001 From: Egor Kislitsyn Date: Mon, 9 Dec 2019 19:12:24 +0700 Subject: Set Plug.Logger to log at `:debug` level --- lib/pleroma/web/endpoint.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/web/endpoint.ex b/lib/pleroma/web/endpoint.ex index 49735b5c2..5fcce7ca2 100644 --- 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( Plug.Parsers, -- cgit v1.2.3 From b7a57d8e388a03d7d92248aa8c583365bde9d0b1 Mon Sep 17 00:00:00 2001 From: Egor Kislitsyn Date: Tue, 10 Dec 2019 00:38:01 +0700 Subject: Use Pleroma.Utils.compile_dir/1 in Pleroma.HTML.compile_scrubbers/0 --- lib/pleroma/html.ex | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/html.ex b/lib/pleroma/html.ex index 2cae29f35..11513106e 100644 --- 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" -- cgit v1.2.3 From a37bd5c25587528b9f7a8ac1d148f6a4eb171769 Mon Sep 17 00:00:00 2001 From: Egor Kislitsyn Date: Tue, 10 Dec 2019 15:08:57 +0700 Subject: Change log level --- lib/pleroma/object/fetcher.ex | 2 +- lib/pleroma/web/activity_pub/publisher.ex | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/object/fetcher.ex b/lib/pleroma/object/fetcher.ex index 4d71c91a8..a1bde90f1 100644 --- 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/web/activity_pub/publisher.ex b/lib/pleroma/web/activity_pub/publisher.ex index 4ea37fc7b..e834f43ad 100644 --- a/lib/pleroma/web/activity_pub/publisher.ex +++ b/lib/pleroma/web/activity_pub/publisher.ex @@ -47,7 +47,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()) -- cgit v1.2.3 From ee6805850c8a86105b7f16d0510cf8465ba24452 Mon Sep 17 00:00:00 2001 From: Egor Kislitsyn Date: Wed, 11 Dec 2019 17:46:07 +0700 Subject: Set log level to debug for not important messages --- lib/pleroma/web/activity_pub/activity_pub_controller.ex | 6 +++--- lib/pleroma/web/activity_pub/mrf/drop_policy.ex | 2 +- lib/pleroma/web/activity_pub/mrf/mediaproxy_warming_policy.ex | 2 +- lib/pleroma/web/activity_pub/publisher.ex | 2 +- lib/pleroma/web/federator/federator.ex | 8 ++++---- lib/pleroma/web/federator/publisher.ex | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/activity_pub_controller.ex b/lib/pleroma/web/activity_pub/activity_pub_controller.ex index dec5da0d3..5059e3984 100644 --- 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 index f7831bc3e..4a5709974 100644 --- 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 index 26b8539fe..df774b0f7 100644 --- 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 index e834f43ad..aeaddff64 100644 --- a/lib/pleroma/web/activity_pub/publisher.ex +++ b/lib/pleroma/web/activity_pub/publisher.ex @@ -223,7 +223,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/federator/federator.ex b/lib/pleroma/web/federator/federator.ex index e8a56ebd7..f506a7d24 100644 --- 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 index fb9b26649..1d045c644 100644 --- 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) -- cgit v1.2.3 From 7973cbdb9fa9120306cb5a265a477eeccd315ee6 Mon Sep 17 00:00:00 2001 From: Ivan Tashkinov Date: Sun, 15 Dec 2019 22:32:42 +0300 Subject: OAuthScopesPlug: disallowed nil token (unless with :fallback option). WIP: controller tests modification: OAuth scopes usage. --- lib/pleroma/plugs/oauth_scopes_plug.ex | 9 ++-- lib/pleroma/user.ex | 6 +-- .../controllers/emoji_api_controller.ex | 2 +- .../controllers/pleroma_api_controller.ex | 9 +++- .../web/twitter_api/controllers/util_controller.ex | 57 ++++++++++++++-------- 5 files changed, 53 insertions(+), 30 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/plugs/oauth_scopes_plug.ex b/lib/pleroma/plugs/oauth_scopes_plug.ex index 174a8389c..07c0f7fdb 100644 --- a/lib/pleroma/plugs/oauth_scopes_plug.ex +++ b/lib/pleroma/plugs/oauth_scopes_plug.ex @@ -18,16 +18,13 @@ defmodule Pleroma.Plugs.OAuthScopesPlug do token = assigns[:token] scopes = transform_scopes(scopes, options) - matched_scopes = token && filter_descendants(scopes, token.scopes) + matched_scopes = (token && filter_descendants(scopes, token.scopes)) || [] cond do - is_nil(token) -> - maybe_perform_instance_privacy_check(conn, options) - - op == :| && Enum.any?(matched_scopes) -> + token && op == :| && Enum.any?(matched_scopes) -> conn - op == :& && matched_scopes == scopes -> + token && op == :& && matched_scopes == scopes -> conn options[:fallback] == :proceed_unauthenticated -> diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 706aee2ff..021a542b3 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -1855,9 +1855,9 @@ defmodule Pleroma.User do ]) with {:ok, updated_user} <- update_and_set_cache(changeset) do - if user.is_admin && !updated_user.is_admin do - # Tokens & authorizations containing any admin scopes must be revoked (revoking all). - # This is an extra safety measure (tokens' admin scopes won't be accepted for non-admins). + if user.is_admin != updated_user.is_admin do + # Admin status change results in change of accessible OAuth scopes, and instead of changing + # already issued tokens we revoke them, requiring user to sign in again global_sign_out(user) end diff --git a/lib/pleroma/web/pleroma_api/controllers/emoji_api_controller.ex b/lib/pleroma/web/pleroma_api/controllers/emoji_api_controller.ex index 69dfa92e3..0bbf84fd3 100644 --- a/lib/pleroma/web/pleroma_api/controllers/emoji_api_controller.ex +++ b/lib/pleroma/web/pleroma_api/controllers/emoji_api_controller.ex @@ -52,7 +52,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIController do @doc """ Lists the packs available on the instance as JSON. - The information is public and does not require authentification. The format is + The information is public and does not require authentication. The format is a map of "pack directory name" to pack.json contents. """ def list_packs(conn, _params) do diff --git a/lib/pleroma/web/pleroma_api/controllers/pleroma_api_controller.ex b/lib/pleroma/web/pleroma_api/controllers/pleroma_api_controller.ex index 8fed3f5bb..772c535a4 100644 --- a/lib/pleroma/web/pleroma_api/controllers/pleroma_api_controller.ex +++ b/lib/pleroma/web/pleroma_api/controllers/pleroma_api_controller.ex @@ -22,7 +22,14 @@ defmodule Pleroma.Web.PleromaAPI.PleromaAPIController do plug( OAuthScopesPlug, - %{scopes: ["read:statuses"]} when action in [:conversation, :conversation_statuses] + %{scopes: ["read:statuses"]} + when action in [:conversation, :conversation_statuses, :emoji_reactions_by] + ) + + plug( + OAuthScopesPlug, + %{scopes: ["write:statuses"]} + when action in [:react_with_emoji, :unreact_with_emoji] ) plug( diff --git a/lib/pleroma/web/twitter_api/controllers/util_controller.ex b/lib/pleroma/web/twitter_api/controllers/util_controller.ex index 2305bb413..849783d4a 100644 --- a/lib/pleroma/web/twitter_api/controllers/util_controller.ex +++ b/lib/pleroma/web/twitter_api/controllers/util_controller.ex @@ -22,7 +22,14 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do plug( OAuthScopesPlug, %{scopes: ["follow", "write:follows"]} - when action in [:do_remote_follow, :follow_import] + when action == :follow_import + ) + + # Note: follower can submit the form (with password auth) not being signed in (having no token) + plug( + OAuthScopesPlug, + %{fallback: :proceed_unauthenticated, scopes: ["follow", "write:follows"]} + when action == :do_remote_follow ) plug(OAuthScopesPlug, %{scopes: ["follow", "write:blocks"]} when action == :blocks_import) @@ -112,6 +119,28 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do end end + def do_remote_follow(%{assigns: %{user: user}} = conn, %{"user" => %{"id" => id}}) + when not is_nil(user) do + with {:fetch_user, %User{} = followee} <- {:fetch_user, User.get_cached_by_id(id)}, + {:ok, _follower, _followee, _activity} <- CommonAPI.follow(user, followee) do + conn + |> render("followed.html", %{error: false}) + else + # Was already following user + {:error, "Could not follow user:" <> _rest} -> + render(conn, "followed.html", %{error: "Error following account"}) + + {:fetch_user, error} -> + Logger.debug("Remote follow failed with error #{inspect(error)}") + render(conn, "followed.html", %{error: "Could not find user"}) + + e -> + Logger.debug("Remote follow failed with error #{inspect(e)}") + render(conn, "followed.html", %{error: "Something went wrong."}) + end + end + + # Note: "id" is the id of followee user, disregard incorrect placing under "authorization" def do_remote_follow(conn, %{ "authorization" => %{"name" => username, "password" => password, "id" => id} }) do @@ -145,24 +174,12 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do end end - def do_remote_follow(%{assigns: %{user: user}} = conn, %{"user" => %{"id" => id}}) do - with {:fetch_user, %User{} = followee} <- {:fetch_user, User.get_cached_by_id(id)}, - {:ok, _follower, _followee, _activity} <- CommonAPI.follow(user, followee) do - conn - |> render("followed.html", %{error: false}) - else - # Was already following user - {:error, "Could not follow user:" <> _rest} -> - render(conn, "followed.html", %{error: "Error following account"}) - - {:fetch_user, error} -> - Logger.debug("Remote follow failed with error #{inspect(error)}") - render(conn, "followed.html", %{error: "Could not find user"}) + def do_remote_follow(%{assigns: %{user: nil}} = conn, _) do + render(conn, "followed.html", %{error: "Insufficient permissions: follow | write:follows."}) + end - e -> - Logger.debug("Remote follow failed with error #{inspect(e)}") - render(conn, "followed.html", %{error: "Something went wrong."}) - end + def do_remote_follow(conn, _) do + render(conn, "followed.html", %{error: "Something went wrong."}) end def notifications_read(%{assigns: %{user: user}} = conn, %{"id" => notification_id}) do @@ -345,7 +362,9 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do end def delete_account(%{assigns: %{user: user}} = conn, params) do - case CommonAPI.Utils.confirm_current_password(user, params["password"]) do + password = params["password"] || "" + + case CommonAPI.Utils.confirm_current_password(user, password) do {:ok, user} -> User.delete(user) json(conn, %{status: "success"}) -- cgit v1.2.3 From 404a9ccb9a220f3f52ee03bd69bd3746d95794cc Mon Sep 17 00:00:00 2001 From: Maxim Filippov Date: Wed, 18 Dec 2019 23:11:42 +0300 Subject: Stats: return status counts by scope --- lib/pleroma/stats.ex | 72 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 67 insertions(+), 5 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/stats.ex b/lib/pleroma/stats.ex index 8154a09b7..c90e8f409 100644 --- a/lib/pleroma/stats.ex +++ b/lib/pleroma/stats.ex @@ -3,11 +3,15 @@ # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Stats do + use GenServer + import Ecto.Query + + alias Pleroma.Object alias Pleroma.Repo alias Pleroma.User - use GenServer + require Pleroma.Constants @interval 1000 * 60 * 60 @@ -56,7 +60,7 @@ defmodule Pleroma.Stats do %{peers: [], stats: %{}} end - defp get_stat_data do + def get_stat_data do peers = from( u in User, @@ -68,13 +72,71 @@ defmodule Pleroma.Stats do domain_count = Enum.count(peers) - status_count = Repo.aggregate(User.Query.build(%{local: true}), :sum, :note_count) - user_count = Repo.aggregate(User.Query.build(%{local: true, active: true}), :count, :id) %{ peers: peers, - stats: %{domain_count: domain_count, status_count: status_count, user_count: user_count} + stats: %{domain_count: domain_count, status_count: status_count(), user_count: user_count} } end + + defp status_count do + %{ + all: get_all_statuses_count(), + public: public_statuses_query() |> Repo.aggregate(:count, :id), + unlisted: unlisted_statuses_query() |> Repo.aggregate(:count, :id), + direct: direct_statuses_query() |> Repo.aggregate(:count, :id), + private: private_statuses_query() |> Repo.aggregate(:count, :id) + } + end + + defp get_all_statuses_count do + Repo.aggregate(User.Query.build(%{local: true}), :sum, :note_count) + end + + def public_statuses_query do + from(o in Object, + where: fragment("(?)->'to' \\? ?", o.data, ^Pleroma.Constants.as_public()) + ) + end + + def unlisted_statuses_query do + from(o in Object, + where: not fragment("(?)->'to' \\? ?", o.data, ^Pleroma.Constants.as_public()), + where: fragment("(?)->'cc' \\? ?", o.data, ^Pleroma.Constants.as_public()) + ) + end + + def direct_statuses_query do + private_statuses_ids = from(p in private_statuses_query(), select: p.id) |> Repo.all() + + from(o in Object, + where: + fragment( + "? \\? 'directMessage' AND (?->>'directMessage')::boolean = true", + o.data, + o.data + ) or + (not fragment("(?)->'to' \\? ?", o.data, ^Pleroma.Constants.as_public()) and + not fragment("(?)->'cc' \\? ?", o.data, ^Pleroma.Constants.as_public()) and + o.id not in ^private_statuses_ids) + ) + end + + def private_statuses_query do + from(o in subquery(recipients_query()), + where: ilike(o.recipients, "%/followers%") + ) + end + + defp recipients_query do + from(o in Object, + select: %{ + id: o.id, + recipients: fragment("jsonb_array_elements_text((?)->'to')", o.data) + }, + where: not fragment("(?)->'to' \\? ?", o.data, ^Pleroma.Constants.as_public()), + where: not fragment("(?)->'cc' \\? ?", o.data, ^Pleroma.Constants.as_public()) + ) + end end -- cgit v1.2.3 From 432b3067d4c62cd27e35f0b6e7bdc61da63310b9 Mon Sep 17 00:00:00 2001 From: Egor Kislitsyn Date: Thu, 19 Dec 2019 19:25:23 +0700 Subject: Do not crash when remote user follower and following counters are hidden --- lib/pleroma/web/activity_pub/activity_pub.ex | 40 +++++++++++----------------- 1 file changed, 16 insertions(+), 24 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 16e6b0057..60c9e7e64 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -1298,28 +1298,26 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do def fetch_follow_information_for_user(user) do with {:ok, following_data} <- Fetcher.fetch_and_contain_remote_object_from_id(user.following_address), - following_count when is_integer(following_count) <- following_data["totalItems"], {:ok, hide_follows} <- collection_private(following_data), {:ok, followers_data} <- Fetcher.fetch_and_contain_remote_object_from_id(user.follower_address), - followers_count when is_integer(followers_count) <- followers_data["totalItems"], {:ok, hide_followers} <- collection_private(followers_data) do {:ok, %{ hide_follows: hide_follows, - follower_count: followers_count, - following_count: following_count, + follower_count: normalize_counter(followers_data["totalItems"]), + following_count: normalize_counter(following_data["totalItems"]), hide_followers: hide_followers }} else - {:error, _} = e -> - e - - e -> - {:error, e} + {:error, _} = e -> e + e -> {:error, e} end end + defp normalize_counter(counter) when is_integer(counter), do: counter + defp normalize_counter(_), do: 0 + defp maybe_update_follow_information(data) do with {:enabled, true} <- {:enabled, Pleroma.Config.get([:instance, :external_user_synchronization])}, @@ -1339,24 +1337,18 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do end end + defp collection_private(%{"first" => %{"type" => type}}) + when type in ["CollectionPage", "OrderedCollectionPage"], + do: {:ok, false} + defp collection_private(%{"first" => first}) do - if is_map(first) and - first["type"] in ["CollectionPage", "OrderedCollectionPage"] do + with {:ok, %{"type" => type}} when type in ["CollectionPage", "OrderedCollectionPage"] <- + Fetcher.fetch_and_contain_remote_object_from_id(first) do {:ok, false} else - with {:ok, %{"type" => type}} when type in ["CollectionPage", "OrderedCollectionPage"] <- - Fetcher.fetch_and_contain_remote_object_from_id(first) do - {:ok, false} - else - {:error, {:ok, %{status: code}}} when code in [401, 403] -> - {:ok, true} - - {:error, _} = e -> - e - - e -> - {:error, e} - end + {:error, {:ok, %{status: code}}} when code in [401, 403] -> {:ok, true} + {:error, _} = e -> e + e -> {:error, e} end end -- cgit v1.2.3 From 455e072d27f28c39050b2dc24b346a8f2ef30f90 Mon Sep 17 00:00:00 2001 From: Ivan Tashkinov Date: Thu, 19 Dec 2019 17:23:27 +0300 Subject: [#2068] Introduced proper OAuth tokens usage to controller tests. --- lib/pleroma/web/masto_fe_controller.ex | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/masto_fe_controller.ex b/lib/pleroma/web/masto_fe_controller.ex index ca261ad6e..9f7e4943c 100644 --- a/lib/pleroma/web/masto_fe_controller.ex +++ b/lib/pleroma/web/masto_fe_controller.ex @@ -20,18 +20,21 @@ defmodule Pleroma.Web.MastoFEController do plug(Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug when action != :index) @doc "GET /web/*path" - def index(%{assigns: %{user: user}} = conn, _params) do - token = get_session(conn, :oauth_token) + def index(%{assigns: %{user: user, token: token}} = conn, _params) + when not is_nil(user) and not is_nil(token) do + conn + |> put_layout(false) + |> render("index.html", + token: token.token, + user: user, + custom_emojis: Pleroma.Emoji.get_all() + ) + end - if user && token do - conn - |> put_layout(false) - |> render("index.html", token: token, user: user, custom_emojis: Pleroma.Emoji.get_all()) - else - conn - |> put_session(:return_to, conn.request_path) - |> redirect(to: "/web/login") - end + def index(conn, _params) do + conn + |> put_session(:return_to, conn.request_path) + |> redirect(to: "/web/login") end @doc "GET /web/manifest.json" -- cgit v1.2.3 From 5fc84552d311efd606f66775c55862b3d11ad258 Mon Sep 17 00:00:00 2001 From: Maxim Filippov Date: Thu, 19 Dec 2019 19:52:55 +0300 Subject: Fix all count --- lib/pleroma/stats.ex | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/stats.ex b/lib/pleroma/stats.ex index c90e8f409..97e8b1990 100644 --- a/lib/pleroma/stats.ex +++ b/lib/pleroma/stats.ex @@ -82,7 +82,7 @@ defmodule Pleroma.Stats do defp status_count do %{ - all: get_all_statuses_count(), + all: all_statuses_query() |> Repo.aggregate(:count, :id), public: public_statuses_query() |> Repo.aggregate(:count, :id), unlisted: unlisted_statuses_query() |> Repo.aggregate(:count, :id), direct: direct_statuses_query() |> Repo.aggregate(:count, :id), @@ -90,8 +90,8 @@ defmodule Pleroma.Stats do } end - defp get_all_statuses_count do - Repo.aggregate(User.Query.build(%{local: true}), :sum, :note_count) + defp all_statuses_query do + from(o in Object, where: fragment("(?)->>'type' = 'Note'", o.data)) end def public_statuses_query do -- cgit v1.2.3 From 06ae56a3ae93c494f9c5d15b097d75c6ab7fcc29 Mon Sep 17 00:00:00 2001 From: Mark Felder Date: Fri, 20 Dec 2019 16:32:04 -0600 Subject: Posts without media attachments should get the Summary TwitterCard --- lib/pleroma/web/metadata/twitter_card.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/web/metadata/twitter_card.ex b/lib/pleroma/web/metadata/twitter_card.ex index d6a6049b3..67419a666 100644 --- a/lib/pleroma/web/metadata/twitter_card.ex +++ b/lib/pleroma/web/metadata/twitter_card.ex @@ -31,7 +31,7 @@ defmodule Pleroma.Web.Metadata.Providers.TwitterCard do if attachments == [] or Metadata.activity_nsfw?(object) do [ image_tag(user), - {:meta, [property: "twitter:card", content: "summary_large_image"], []} + {:meta, [property: "twitter:card", content: "summary"], []} ] else attachments -- cgit v1.2.3 From e71a13ad57d2604b45c0beb278f47d25c284783a Mon Sep 17 00:00:00 2001 From: Maxim Filippov Date: Sat, 21 Dec 2019 11:41:19 +0000 Subject: Revert "Merge branch 'feature/status-counts-by-scope' into 'develop'" This reverts merge request !2076 --- lib/pleroma/stats.ex | 72 ++++------------------------------------------------ 1 file changed, 5 insertions(+), 67 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/stats.ex b/lib/pleroma/stats.ex index 97e8b1990..8154a09b7 100644 --- a/lib/pleroma/stats.ex +++ b/lib/pleroma/stats.ex @@ -3,15 +3,11 @@ # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Stats do - use GenServer - import Ecto.Query - - alias Pleroma.Object alias Pleroma.Repo alias Pleroma.User - require Pleroma.Constants + use GenServer @interval 1000 * 60 * 60 @@ -60,7 +56,7 @@ defmodule Pleroma.Stats do %{peers: [], stats: %{}} end - def get_stat_data do + defp get_stat_data do peers = from( u in User, @@ -72,71 +68,13 @@ defmodule Pleroma.Stats do domain_count = Enum.count(peers) + status_count = Repo.aggregate(User.Query.build(%{local: true}), :sum, :note_count) + user_count = Repo.aggregate(User.Query.build(%{local: true, active: true}), :count, :id) %{ peers: peers, - stats: %{domain_count: domain_count, status_count: status_count(), user_count: user_count} + stats: %{domain_count: domain_count, status_count: status_count, user_count: user_count} } end - - defp status_count do - %{ - all: all_statuses_query() |> Repo.aggregate(:count, :id), - public: public_statuses_query() |> Repo.aggregate(:count, :id), - unlisted: unlisted_statuses_query() |> Repo.aggregate(:count, :id), - direct: direct_statuses_query() |> Repo.aggregate(:count, :id), - private: private_statuses_query() |> Repo.aggregate(:count, :id) - } - end - - defp all_statuses_query do - from(o in Object, where: fragment("(?)->>'type' = 'Note'", o.data)) - end - - def public_statuses_query do - from(o in Object, - where: fragment("(?)->'to' \\? ?", o.data, ^Pleroma.Constants.as_public()) - ) - end - - def unlisted_statuses_query do - from(o in Object, - where: not fragment("(?)->'to' \\? ?", o.data, ^Pleroma.Constants.as_public()), - where: fragment("(?)->'cc' \\? ?", o.data, ^Pleroma.Constants.as_public()) - ) - end - - def direct_statuses_query do - private_statuses_ids = from(p in private_statuses_query(), select: p.id) |> Repo.all() - - from(o in Object, - where: - fragment( - "? \\? 'directMessage' AND (?->>'directMessage')::boolean = true", - o.data, - o.data - ) or - (not fragment("(?)->'to' \\? ?", o.data, ^Pleroma.Constants.as_public()) and - not fragment("(?)->'cc' \\? ?", o.data, ^Pleroma.Constants.as_public()) and - o.id not in ^private_statuses_ids) - ) - end - - def private_statuses_query do - from(o in subquery(recipients_query()), - where: ilike(o.recipients, "%/followers%") - ) - end - - defp recipients_query do - from(o in Object, - select: %{ - id: o.id, - recipients: fragment("jsonb_array_elements_text((?)->'to')", o.data) - }, - where: not fragment("(?)->'to' \\? ?", o.data, ^Pleroma.Constants.as_public()), - where: not fragment("(?)->'cc' \\? ?", o.data, ^Pleroma.Constants.as_public()) - ) - end end -- cgit v1.2.3 From 70410dfafd272bd1f38602446cc4f6e83645326f Mon Sep 17 00:00:00 2001 From: Maksim Pechnikov Date: Wed, 8 Jan 2020 16:40:38 +0300 Subject: fix create service actor --- lib/pleroma/user.ex | 53 ++++++++++++++++++++++++++--------- lib/pleroma/web/activity_pub/relay.ex | 4 ++- 2 files changed, 43 insertions(+), 14 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 706aee2ff..7ce9e17df 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -1430,20 +1430,47 @@ defmodule Pleroma.User do Creates an internal service actor by URI if missing. Optionally takes nickname for addressing. """ - def get_or_create_service_actor_by_ap_id(uri, nickname \\ nil) do - with user when is_nil(user) <- get_cached_by_ap_id(uri) do - {:ok, user} = - %User{ - invisible: true, - local: true, - ap_id: uri, - nickname: nickname, - follower_address: uri <> "/followers" - } - |> Repo.insert() + @spec get_or_create_service_actor_by_ap_id(String.t(), String.t()) :: User.t() | nil + def get_or_create_service_actor_by_ap_id(uri, nickname) do + {_, user} = + case get_cached_by_ap_id(uri) do + nil -> + with {:error, %{errors: errors}} <- create_service_actor(uri, nickname) do + Logger.error("Cannot create service actor: #{uri}/.\n#{inspect(errors)}") + {:error, nil} + end - user - end + %User{invisible: false} = user -> + set_invisible(user) + + user -> + {:ok, user} + end + + user + end + + @spec set_invisible(User.t()) :: {:ok, User.t()} + defp set_invisible(user) do + user + |> change(%{invisible: true}) + |> update_and_set_cache() + end + + @spec create_service_actor(String.t(), String.t()) :: + {:ok, User.t()} | {:error, Ecto.Changeset.t()} + defp create_service_actor(uri, nickname) do + %User{ + invisible: true, + local: true, + ap_id: uri, + nickname: nickname, + follower_address: uri <> "/followers" + } + |> change + |> unique_constraint(:nickname) + |> Repo.insert() + |> set_cache() end # AP style diff --git a/lib/pleroma/web/activity_pub/relay.ex b/lib/pleroma/web/activity_pub/relay.ex index 99a804568..48a1b71e0 100644 --- a/lib/pleroma/web/activity_pub/relay.ex +++ b/lib/pleroma/web/activity_pub/relay.ex @@ -9,10 +9,12 @@ defmodule Pleroma.Web.ActivityPub.Relay do alias Pleroma.Web.ActivityPub.ActivityPub require Logger + @relay_nickname "relay" + def get_actor do actor = relay_ap_id() - |> User.get_or_create_service_actor_by_ap_id() + |> User.get_or_create_service_actor_by_ap_id(@relay_nickname) actor end -- cgit v1.2.3 From 0c9c62509d10c19e2e6d796cb431f1560e9e88b1 Mon Sep 17 00:00:00 2001 From: Hakaba Hitoyo Date: Sat, 11 Jan 2020 17:19:54 +0000 Subject: Remove MDII uploader --- lib/pleroma/uploaders/mdii.ex | 37 ------------------------------------- 1 file changed, 37 deletions(-) delete mode 100644 lib/pleroma/uploaders/mdii.ex (limited to 'lib') diff --git a/lib/pleroma/uploaders/mdii.ex b/lib/pleroma/uploaders/mdii.ex deleted file mode 100644 index c36f3d61d..000000000 --- a/lib/pleroma/uploaders/mdii.ex +++ /dev/null @@ -1,37 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.Uploaders.MDII do - @moduledoc "Represents uploader for https://github.com/hakaba-hitoyo/minimal-digital-image-infrastructure" - - alias Pleroma.Config - alias Pleroma.HTTP - - @behaviour Pleroma.Uploaders.Uploader - - # MDII-hosted images are never passed through the MediaPlug; only local media. - # Delegate to Pleroma.Uploaders.Local - def get_file(file) do - Pleroma.Uploaders.Local.get_file(file) - end - - def put_file(upload) do - cgi = Config.get([Pleroma.Uploaders.MDII, :cgi]) - files = Config.get([Pleroma.Uploaders.MDII, :files]) - - {:ok, file_data} = File.read(upload.tempfile) - - extension = String.split(upload.name, ".") |> List.last() - query = "#{cgi}?#{extension}" - - with {:ok, %{status: 200, body: body}} <- - HTTP.post(query, file_data, [], adapter: [pool: :default]) do - remote_file_name = String.split(body) |> List.first() - public_url = "#{files}/#{remote_file_name}.#{extension}" - {:ok, {:url, public_url}} - else - _ -> Pleroma.Uploaders.Local.put_file(upload) - end - end -end -- cgit v1.2.3