From 8d06be35e0f1cb5caa2b638330c8bb03ad08a127 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Sat, 17 Nov 2018 15:51:02 +0000 Subject: activitypub: utils: add determine_explicit_mentions() and tests --- lib/pleroma/web/activity_pub/utils.ex | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index d2e457a68..d516818d9 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -25,6 +25,20 @@ defmodule Pleroma.Web.ActivityPub.Utils do Map.put(params, "actor", get_ap_id(params["actor"])) end + def determine_explicit_mentions(%{"tag" => tag} = _object) when is_list(tag) do + tag + |> Enum.filter(fn x -> is_map(x) end) + |> Enum.filter(fn x -> x["type"] == "Mention" end) + |> Enum.map(fn x -> x["href"] end) + end + + def determine_explicit_mentions(%{"tag" => tag} = object) when is_map(tag) do + Map.put(object, "tag", [tag]) + |> determine_explicit_mentions() + end + + def determine_explicit_mentions(_), do: [] + defp recipient_in_collection(ap_id, coll) when is_binary(coll), do: ap_id == coll defp recipient_in_collection(ap_id, coll) when is_list(coll), do: ap_id in coll defp recipient_in_collection(_, _), do: false -- cgit v1.2.3 From 681f40ee5c4de644c79f71bb6671c4c63b18e68a Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Sat, 17 Nov 2018 16:05:41 +0000 Subject: activitypub: transmogrifier: fix up to/cc addressing brain damage caused by mastodon-style explicit DMs --- lib/pleroma/web/activity_pub/transmogrifier.ex | 42 ++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 6 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index fa3abe3d8..e9a801cf5 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -93,12 +93,42 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do end end - def fix_addressing(map) do - map - |> fix_addressing_list("to") - |> fix_addressing_list("cc") - |> fix_addressing_list("bto") - |> fix_addressing_list("bcc") + def fix_explicit_addressing(%{"to" => to, "cc" => cc} = object, explicit_mentions) do + explicit_to = + to + |> Enum.filter(fn x -> x in explicit_mentions end) + + explicit_cc = + to + |> Enum.filter(fn x -> x not in explicit_mentions end) + + final_cc = + (cc ++ explicit_cc) + |> Enum.uniq() + + object + |> Map.put("to", explicit_to) + |> Map.put("cc", final_cc) + end + + def fix_explicit_addressing(object, _explicit_mentions), do: object + + def fix_addressing(object) do + object = + object + |> fix_addressing_list("to") + |> fix_addressing_list("cc") + |> fix_addressing_list("bto") + |> fix_addressing_list("bcc") + + explicit_mentions = + object + |> Utils.determine_explicit_mentions() + + explicit_mentions = explicit_mentions ++ ["https://www.w3.org/ns/activitystreams#Public"] + + object + |> fix_explicit_addressing(explicit_mentions) end def fix_actor(%{"attributedTo" => actor} = object) do -- cgit v1.2.3 From 75dfa1f0b07806908b11735afab3ba0dd3149659 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Sat, 17 Nov 2018 16:30:44 +0000 Subject: mastodon api: get_visibility(): DMs never have a cc list. --- lib/pleroma/web/mastodon_api/views/status_view.ex | 3 +++ 1 file changed, 3 insertions(+) (limited to 'lib') diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex index 7f5a52ea3..feabf54c6 100644 --- a/lib/pleroma/web/mastodon_api/views/status_view.ex +++ b/lib/pleroma/web/mastodon_api/views/status_view.ex @@ -231,6 +231,9 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do Enum.any?(to, &String.contains?(&1, "/followers")) -> "private" + length(cc) > 0 -> + "private" + true -> "direct" end -- cgit v1.2.3 From 9adc80afff5ea42e1773c6ada5e078ec6c1cadc8 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Sun, 23 Dec 2018 15:26:07 +0000 Subject: common api: set directMessage flag on our own posts --- lib/pleroma/web/common_api/common_api.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/web/common_api/common_api.ex b/lib/pleroma/web/common_api/common_api.ex index 504670439..7084da6de 100644 --- a/lib/pleroma/web/common_api/common_api.ex +++ b/lib/pleroma/web/common_api/common_api.ex @@ -143,7 +143,7 @@ defmodule Pleroma.Web.CommonAPI do actor: user, context: context, object: object, - additional: %{"cc" => cc} + additional: %{"cc" => cc, "directMessage" => visibility == "direct"} }) res -- cgit v1.2.3 From ddae43eb43c5c63eeb0e93e60917b99b3ffb41d0 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Sun, 23 Dec 2018 15:27:08 +0000 Subject: activitypub: add is_private?/is_direct? helpers --- lib/pleroma/web/activity_pub/activity_pub.ex | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 130c06028..1fedfa854 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -805,6 +805,14 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do "https://www.w3.org/ns/activitystreams#Public" in (data["to"] ++ (data["cc"] || [])) end + def is_private?(activity) do + !is_public?(activity) && Enum.any?(activity.data["to"], &String.contains?(&1, "/followers")) + end + + def is_direct?(activity) do + !is_public?(activity) && !is_private?(activity) + end + def visible_for_user?(activity, nil) do is_public?(activity) end -- cgit v1.2.3 From 420651157becb8fac62e651d14376b6334316121 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Sun, 23 Dec 2018 15:35:49 +0000 Subject: transmogrifier: don't apply heuristics against messages which have `directMessage` set true --- lib/pleroma/web/activity_pub/transmogrifier.ex | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index e9a801cf5..5400aa657 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -113,14 +113,10 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do def fix_explicit_addressing(object, _explicit_mentions), do: object - def fix_addressing(object) do - object = - object - |> fix_addressing_list("to") - |> fix_addressing_list("cc") - |> fix_addressing_list("bto") - |> fix_addressing_list("bcc") + # if directMessage flag is set to true, leave the addressing alone + def fix_explicit_addressing(%{"directMessage" => true} = object), do: object + def fix_explicit_addressing(object) do explicit_mentions = object |> Utils.determine_explicit_mentions() @@ -131,6 +127,14 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do |> fix_explicit_addressing(explicit_mentions) end + def fix_addressing(object) do + object + |> fix_addressing_list("to") + |> fix_addressing_list("cc") + |> fix_addressing_list("bto") + |> fix_addressing_list("bcc") + end + def fix_actor(%{"attributedTo" => actor} = object) do object |> Map.put("actor", get_actor(%{"actor" => actor})) @@ -363,6 +367,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do data = Map.put(data, "actor", actor) |> fix_addressing + |> fix_explicit_addressing with nil <- Activity.get_create_activity_by_object_ap_id(object["id"]), %User{} = user <- User.get_or_fetch_by_ap_id(data["actor"]) do @@ -378,6 +383,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do additional: Map.take(data, [ "cc", + "directMessage", "id" ]) } -- cgit v1.2.3 From 7c9749f793aa0970a36742bf4177c1a9899b1ff4 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Sun, 23 Dec 2018 15:44:26 +0000 Subject: transmogrifier: slightly clean up fix_explicit_addressing pipeline --- lib/pleroma/web/activity_pub/transmogrifier.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index 5400aa657..5d3feccfe 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -133,6 +133,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do |> fix_addressing_list("cc") |> fix_addressing_list("bto") |> fix_addressing_list("bcc") + |> fix_explicit_addressing end def fix_actor(%{"attributedTo" => actor} = object) do @@ -367,7 +368,6 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do data = Map.put(data, "actor", actor) |> fix_addressing - |> fix_explicit_addressing with nil <- Activity.get_create_activity_by_object_ap_id(object["id"]), %User{} = user <- User.get_or_fetch_by_ap_id(data["actor"]) do -- cgit v1.2.3 From aa37313416c155a37b40e09617eb2fe524edbf0b Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Sun, 20 Jan 2019 02:30:29 +0000 Subject: activitypub: short-circuit is_public?() with directMessage flag check --- lib/pleroma/web/activity_pub/activity_pub.ex | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 1fedfa854..68b684c4b 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -800,6 +800,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do def is_public?(%Object{data: %{"type" => "Tombstone"}}), do: false def is_public?(%Object{data: data}), do: is_public?(data) def is_public?(%Activity{data: data}), do: is_public?(data) + def is_public?(%{"directMessage" => true}), do: false def is_public?(data) do "https://www.w3.org/ns/activitystreams#Public" in (data["to"] ++ (data["cc"] || [])) @@ -809,6 +810,9 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do !is_public?(activity) && Enum.any?(activity.data["to"], &String.contains?(&1, "/followers")) end + def is_direct?(%Activity{data: %{"directMessage" => true}}), do: true + def is_direct?(%Object{data: %{"directMessage" => true}}), do: true + def is_direct?(activity) do !is_public?(activity) && !is_private?(activity) end -- cgit v1.2.3 From aa480f4a8b46f24a07491228462b4318ca25eda7 Mon Sep 17 00:00:00 2001 From: Ivan Tashkinov Date: Mon, 21 Jan 2019 14:16:51 +0300 Subject: [#530] Prevents user `info` from being overwritten because of race conditions and non-partial update of embed (in WebFinger.ensure_keys_present and other places). --- lib/pleroma/web/activity_pub/activity_pub.ex | 10 ++++++---- 1 file changed, 6 insertions(+), 4 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 0431d62af..32c08c9d2 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -140,8 +140,9 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do additional ), {:ok, activity} <- insert(create_data, local), - :ok <- maybe_federate(activity), - {:ok, _actor} <- User.increase_note_count(actor) do + # Changing note count prior to federation in order not to reload `actor` (potentially updated by federator) + {:ok, _actor} <- User.increase_note_count(actor), + :ok <- maybe_federate(activity) do {:ok, activity} end end @@ -288,8 +289,9 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do with {:ok, _} <- Object.delete(object), {:ok, activity} <- insert(data, local), - :ok <- maybe_federate(activity), - {:ok, _actor} <- User.decrease_note_count(user) do + # Changing note count prior to federation in order not to reload `actor` (potentially updated by federator) + {:ok, _actor} <- User.decrease_note_count(user), + :ok <- maybe_federate(activity) do {:ok, activity} end end -- cgit v1.2.3 From a4d3fec8a71241d5c40fa76e33f15fa217154600 Mon Sep 17 00:00:00 2001 From: Ivan Tashkinov Date: Mon, 21 Jan 2019 14:52:41 +0300 Subject: [#502] Code comments update. --- lib/pleroma/web/activity_pub/activity_pub.ex | 4 ++-- 1 file changed, 2 insertions(+), 2 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 32c08c9d2..fd026a047 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -140,7 +140,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do additional ), {:ok, activity} <- insert(create_data, local), - # Changing note count prior to federation in order not to reload `actor` (potentially updated by federator) + # Changing note count prior to enqueuing federation task in order to avoid race conditions on updating user.info {:ok, _actor} <- User.increase_note_count(actor), :ok <- maybe_federate(activity) do {:ok, activity} @@ -289,7 +289,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do with {:ok, _} <- Object.delete(object), {:ok, activity} <- insert(data, local), - # Changing note count prior to federation in order not to reload `actor` (potentially updated by federator) + # Changing note count prior to enqueuing federation task in order to avoid race conditions on updating user.info {:ok, _actor} <- User.decrease_note_count(user), :ok <- maybe_federate(activity) do {:ok, activity} -- cgit v1.2.3 From 99763999c19bfb2a5d8a10af98ff3c54d2c929ce Mon Sep 17 00:00:00 2001 From: href Date: Mon, 21 Jan 2019 15:17:24 +0100 Subject: reverse_proxy - always override plug's cache-control --- lib/pleroma/reverse_proxy.ex | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/reverse_proxy.ex b/lib/pleroma/reverse_proxy.ex index a3846c3bb..a25b5ea4e 100644 --- a/lib/pleroma/reverse_proxy.ex +++ b/lib/pleroma/reverse_proxy.ex @@ -275,11 +275,24 @@ defmodule Pleroma.ReverseProxy do defp build_resp_cache_headers(headers, _opts) do has_cache? = Enum.any?(headers, fn {k, _} -> k in @resp_cache_headers end) - - if has_cache? do - headers - else - List.keystore(headers, "cache-control", 0, {"cache-control", @default_cache_control_header}) + has_cache_control? = List.keymember?(headers, "cache-control", 0) + + cond do + has_cache? && has_cache_control? -> + headers + + has_cache? -> + # There's caching header present but no cache-control -- we need to explicitely override it to public + # as Plug defaults to "max-age=0, private, must-revalidate" + List.keystore(headers, "cache-control", 0, {"cache-control", "public"}) + + true -> + List.keystore( + headers, + "cache-control", + 0, + {"cache-control", @default_cache_control_header} + ) end end -- cgit v1.2.3 From f9a326909979959d6cb43f66177045bb2adccbf4 Mon Sep 17 00:00:00 2001 From: href Date: Mon, 21 Jan 2019 22:44:14 +0100 Subject: Uploader callback controller --- lib/pleroma/uploaders/uploader.ex | 37 ++++++++++++++++++++++++++++++---- lib/pleroma/web/router.ex | 5 +++++ lib/pleroma/web/uploader_controller.ex | 25 +++++++++++++++++++++++ 3 files changed, 63 insertions(+), 4 deletions(-) create mode 100644 lib/pleroma/web/uploader_controller.ex (limited to 'lib') diff --git a/lib/pleroma/uploaders/uploader.ex b/lib/pleroma/uploaders/uploader.ex index 0959d7a3e..ce83cbbbc 100644 --- a/lib/pleroma/uploaders/uploader.ex +++ b/lib/pleroma/uploaders/uploader.ex @@ -27,18 +27,47 @@ defmodule Pleroma.Uploaders.Uploader do This allows to correctly proxy or redirect requests to the backend, while allowing to migrate backends without breaking any URL. * `{url, url :: String.t}` to bypass `get_file/2` and use the `url` directly in the activity. * `{:error, String.t}` error information if the file failed to be saved to the backend. + * `:wait_callback` will wait for an http post request at `/api/pleroma/upload_callback/:upload_path` and call the uploader's `http_callback/3` method. """ + @type file_spec :: {:file | :url, String.t()} @callback put_file(Pleroma.Upload.t()) :: - :ok | {:ok, {:file | :url, String.t()}} | {:error, String.t()} + :ok | {:ok, file_spec()} | {:error, String.t()} | :wait_callback + + @callback http_callback(Plug.Conn.t(), Map.t()) :: + {:ok, Plug.Conn.t()} + | {:ok, Plug.Conn.t(), file_spec()} + | {:error, Plug.Conn.t(), String.t()} + @optional_callbacks http_callback: 2 + + @spec put_file(module(), Pleroma.Upload.t()) :: {:ok, file_spec()} | {:error, String.t()} - @spec put_file(module(), Pleroma.Upload.t()) :: - {:ok, {:file | :url, String.t()}} | {:error, String.t()} def put_file(uploader, upload) do case uploader.put_file(upload) do :ok -> {:ok, {:file, upload.path}} - other -> other + :wait_callback -> handle_callback(uploader, upload) + {:ok, _} = ok -> ok + {:error, _} = error -> error + end + end + + defp handle_callback(uploader, upload) do + :global.register_name({__MODULE__, upload.path}, self()) + + receive do + {__MODULE__, pid, conn, params} -> + case uploader.http_callback(conn, params) do + {:ok, conn, ok} -> + send(pid, {__MODULE__, conn}) + {:ok, ok} + + {:error, conn, error} -> + send(pid, {__MODULE__, conn}) + {:error, error} + end + after + 30_000 -> {:error, "Uploader callback timeout"} end end end diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index 7a0c9fd25..69ab58c6a 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -107,6 +107,11 @@ defmodule Pleroma.Web.Router do get("/captcha", UtilController, :captcha) end + scope "/api/pleroma", Pleroma.Web do + pipe_through(:pleroma_api) + post("/uploader_callback/:upload_path", UploaderController, :callback) + end + scope "/api/pleroma/admin", Pleroma.Web.AdminAPI do pipe_through(:admin_api) delete("/user", AdminAPIController, :user_delete) diff --git a/lib/pleroma/web/uploader_controller.ex b/lib/pleroma/web/uploader_controller.ex new file mode 100644 index 000000000..6c28d1197 --- /dev/null +++ b/lib/pleroma/web/uploader_controller.ex @@ -0,0 +1,25 @@ +defmodule Pleroma.Web.UploaderController do + use Pleroma.Web, :controller + + alias Pleroma.Uploaders.Uploader + + def callback(conn, params = %{"upload_path" => upload_path}) do + process_callback(conn, :global.whereis_name({Uploader, upload_path}), params) + end + + def callbacks(conn, _) do + send_resp(conn, 400, "bad request") + end + + defp process_callback(conn, pid, params) when is_pid(pid) do + send(pid, {Uploader, self(), conn, params}) + + receive do + {Uploader, conn} -> conn + end + end + + defp process_callback(conn, _, _) do + send_resp(conn, 400, "bad request") + end +end -- cgit v1.2.3 From e460820fcfcdc68c3e2a43ee69d587ca261324f8 Mon Sep 17 00:00:00 2001 From: rinpatch Date: Tue, 22 Jan 2019 10:54:11 +0300 Subject: Add get_by_id to activity.ex --- lib/pleroma/activity.ex | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib') diff --git a/lib/pleroma/activity.ex b/lib/pleroma/activity.ex index 353f9f6cd..8fd0311d2 100644 --- a/lib/pleroma/activity.ex +++ b/lib/pleroma/activity.ex @@ -36,6 +36,10 @@ defmodule Pleroma.Activity do ) end + def get_by_id(id) do + Repo.get(Activity, id) + end + # TODO: # Go through these and fix them everywhere. # Wrong name, only returns create activities -- cgit v1.2.3 From 34d59e40086ad8adc020bac6d23ab2aa835f267b Mon Sep 17 00:00:00 2001 From: Ivan Tashkinov Date: Tue, 22 Jan 2019 17:12:53 +0300 Subject: [#502] Fixed User.active_local_user_query to return users with nil or missing `info.deactivated`. Adjusted test. --- lib/pleroma/user.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 06084b117..18137106e 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -901,7 +901,7 @@ defmodule Pleroma.User do def active_local_user_query do from( u in local_user_query(), - where: fragment("?->'deactivated' @> 'false'", u.info) + where: fragment("not (?->'deactivated' @> 'true')", u.info) ) end -- cgit v1.2.3