aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorrinpatch <rinpatch@sdf.org>2020-09-17 12:13:36 +0000
committerrinpatch <rinpatch@sdf.org>2020-09-17 19:48:33 +0300
commit22d49993d9ab35ff5d5276a6a1f4aec96d03b7f3 (patch)
tree957224ba165c8fa73fa5f7dcfe7b97bcf7e35d1d /lib
parenteff7f9892dbb042a447fd83e1ce5e9cb69941cf6 (diff)
downloadpleroma-22d49993d9ab35ff5d5276a6a1f4aec96d03b7f3.tar.gz
Merge branch 'bugfix/mrf-ingestion' into 'develop'
Bugfix: MRF and Pipeline Ingestion See merge request pleroma/secteam/pleroma!15
Diffstat (limited to 'lib')
-rw-r--r--lib/pleroma/web/activity_pub/mrf.ex24
-rw-r--r--lib/pleroma/web/activity_pub/mrf/keyword_policy.ex67
-rw-r--r--lib/pleroma/web/activity_pub/mrf/subchain_policy.ex3
-rw-r--r--lib/pleroma/web/activity_pub/pipeline.ex8
-rw-r--r--lib/pleroma/web/api_spec/operations/chat_operation.ex3
-rw-r--r--lib/pleroma/web/api_spec/operations/status_operation.ex2
-rw-r--r--lib/pleroma/web/common_api/common_api.ex3
-rw-r--r--lib/pleroma/web/pleroma_api/controllers/chat_controller.ex10
8 files changed, 76 insertions, 44 deletions
diff --git a/lib/pleroma/web/activity_pub/mrf.ex b/lib/pleroma/web/activity_pub/mrf.ex
index 206d6af52..5e5361082 100644
--- a/lib/pleroma/web/activity_pub/mrf.ex
+++ b/lib/pleroma/web/activity_pub/mrf.ex
@@ -5,16 +5,34 @@
defmodule Pleroma.Web.ActivityPub.MRF do
@callback filter(Map.t()) :: {:ok | :reject, Map.t()}
- def filter(policies, %{} = object) do
+ def filter(policies, %{} = message) do
policies
- |> Enum.reduce({:ok, object}, fn
- policy, {:ok, object} -> policy.filter(object)
+ |> Enum.reduce({:ok, message}, fn
+ policy, {:ok, message} -> policy.filter(message)
_, error -> error
end)
end
def filter(%{} = object), do: get_policies() |> filter(object)
+ def pipeline_filter(%{} = message, meta) do
+ object = meta[:object_data]
+ ap_id = message["object"]
+
+ if object && ap_id do
+ with {:ok, message} <- filter(Map.put(message, "object", object)) do
+ meta = Keyword.put(meta, :object_data, message["object"])
+ {:ok, Map.put(message, "object", ap_id), meta}
+ else
+ {err, message} -> {err, message, meta}
+ end
+ else
+ {err, message} = filter(message)
+
+ {err, message, meta}
+ end
+ end
+
def get_policies do
Pleroma.Config.get([:mrf, :policies], []) |> get_policies()
end
diff --git a/lib/pleroma/web/activity_pub/mrf/keyword_policy.ex b/lib/pleroma/web/activity_pub/mrf/keyword_policy.ex
index 15e09dcf0..db66cfa3e 100644
--- a/lib/pleroma/web/activity_pub/mrf/keyword_policy.ex
+++ b/lib/pleroma/web/activity_pub/mrf/keyword_policy.ex
@@ -20,9 +20,17 @@ defmodule Pleroma.Web.ActivityPub.MRF.KeywordPolicy do
String.match?(string, pattern)
end
- defp check_reject(%{"object" => %{"content" => content, "summary" => summary}} = message) do
+ defp object_payload(%{} = object) do
+ [object["content"], object["summary"], object["name"]]
+ |> Enum.filter(& &1)
+ |> Enum.join("\n")
+ end
+
+ defp check_reject(%{"object" => %{} = object} = message) do
+ payload = object_payload(object)
+
if Enum.any?(Pleroma.Config.get([:mrf_keyword, :reject]), fn pattern ->
- string_matches?(content, pattern) or string_matches?(summary, pattern)
+ string_matches?(payload, pattern)
end) do
{:reject, "[KeywordPolicy] Matches with rejected keyword"}
else
@@ -30,12 +38,12 @@ defmodule Pleroma.Web.ActivityPub.MRF.KeywordPolicy do
end
end
- defp check_ftl_removal(
- %{"to" => to, "object" => %{"content" => content, "summary" => summary}} = message
- ) do
+ defp check_ftl_removal(%{"to" => to, "object" => %{} = object} = message) do
+ payload = object_payload(object)
+
if Pleroma.Constants.as_public() in to and
Enum.any?(Pleroma.Config.get([:mrf_keyword, :federated_timeline_removal]), fn pattern ->
- string_matches?(content, pattern) or string_matches?(summary, pattern)
+ string_matches?(payload, pattern)
end) do
to = List.delete(to, Pleroma.Constants.as_public())
cc = [Pleroma.Constants.as_public() | message["cc"] || []]
@@ -51,35 +59,24 @@ defmodule Pleroma.Web.ActivityPub.MRF.KeywordPolicy do
end
end
- defp check_replace(%{"object" => %{"content" => content, "summary" => summary}} = message) do
- content =
- if is_binary(content) do
- content
- else
- ""
- end
-
- summary =
- if is_binary(summary) do
- summary
- else
- ""
- end
-
- {content, summary} =
- Enum.reduce(
- Pleroma.Config.get([:mrf_keyword, :replace]),
- {content, summary},
- fn {pattern, replacement}, {content_acc, summary_acc} ->
- {String.replace(content_acc, pattern, replacement),
- String.replace(summary_acc, pattern, replacement)}
- end
- )
-
- {:ok,
- message
- |> put_in(["object", "content"], content)
- |> put_in(["object", "summary"], summary)}
+ defp check_replace(%{"object" => %{} = object} = message) do
+ object =
+ ["content", "name", "summary"]
+ |> Enum.filter(fn field -> Map.has_key?(object, field) && object[field] end)
+ |> Enum.reduce(object, fn field, object ->
+ data =
+ Enum.reduce(
+ Pleroma.Config.get([:mrf_keyword, :replace]),
+ object[field],
+ fn {pat, repl}, acc -> String.replace(acc, pat, repl) end
+ )
+
+ Map.put(object, field, data)
+ end)
+
+ message = Map.put(message, "object", object)
+
+ {:ok, message}
end
@impl true
diff --git a/lib/pleroma/web/activity_pub/mrf/subchain_policy.ex b/lib/pleroma/web/activity_pub/mrf/subchain_policy.ex
index c9f20571f..048052da6 100644
--- a/lib/pleroma/web/activity_pub/mrf/subchain_policy.ex
+++ b/lib/pleroma/web/activity_pub/mrf/subchain_policy.ex
@@ -28,8 +28,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SubchainPolicy do
}"
)
- subchain
- |> MRF.filter(message)
+ MRF.filter(subchain, message)
else
_e -> {:ok, message}
end
diff --git a/lib/pleroma/web/activity_pub/pipeline.ex b/lib/pleroma/web/activity_pub/pipeline.ex
index 36e325c37..2db86f116 100644
--- a/lib/pleroma/web/activity_pub/pipeline.ex
+++ b/lib/pleroma/web/activity_pub/pipeline.ex
@@ -26,13 +26,17 @@ defmodule Pleroma.Web.ActivityPub.Pipeline do
{:error, e} ->
{:error, e}
+
+ {:reject, e} ->
+ {:reject, e}
end
end
def do_common_pipeline(object, meta) do
with {_, {:ok, validated_object, meta}} <-
{:validate_object, ObjectValidator.validate(object, meta)},
- {_, {:ok, mrfd_object}} <- {:mrf_object, MRF.filter(validated_object)},
+ {_, {:ok, mrfd_object, meta}} <-
+ {:mrf_object, MRF.pipeline_filter(validated_object, meta)},
{_, {:ok, activity, meta}} <-
{:persist_object, ActivityPub.persist(mrfd_object, meta)},
{_, {:ok, activity, meta}} <-
@@ -40,7 +44,7 @@ defmodule Pleroma.Web.ActivityPub.Pipeline do
{_, {:ok, _}} <- {:federation, maybe_federate(activity, meta)} do
{:ok, activity, meta}
else
- {:mrf_object, {:reject, _}} -> {:ok, nil, meta}
+ {:mrf_object, {:reject, message, _}} -> {:reject, message}
e -> {:error, e}
end
end
diff --git a/lib/pleroma/web/api_spec/operations/chat_operation.ex b/lib/pleroma/web/api_spec/operations/chat_operation.ex
index b1a0d26ab..56554d5b4 100644
--- a/lib/pleroma/web/api_spec/operations/chat_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/chat_operation.ex
@@ -184,7 +184,8 @@ defmodule Pleroma.Web.ApiSpec.ChatOperation do
"application/json",
ChatMessage
),
- 400 => Operation.response("Bad Request", "application/json", ApiError)
+ 400 => Operation.response("Bad Request", "application/json", ApiError),
+ 422 => Operation.response("MRF Rejection", "application/json", ApiError)
},
security: [
%{
diff --git a/lib/pleroma/web/api_spec/operations/status_operation.ex b/lib/pleroma/web/api_spec/operations/status_operation.ex
index 5bd4619d5..d7ebde6f6 100644
--- a/lib/pleroma/web/api_spec/operations/status_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/status_operation.ex
@@ -55,7 +55,7 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
"application/json",
%Schema{oneOf: [Status, ScheduledStatus]}
),
- 422 => Operation.response("Bad Request", "application/json", ApiError)
+ 422 => Operation.response("Bad Request / MRF Rejection", "application/json", ApiError)
}
}
end
diff --git a/lib/pleroma/web/common_api/common_api.ex b/lib/pleroma/web/common_api/common_api.ex
index 5ad2b91c2..3c7b9e794 100644
--- a/lib/pleroma/web/common_api/common_api.ex
+++ b/lib/pleroma/web/common_api/common_api.ex
@@ -49,6 +49,9 @@ defmodule Pleroma.Web.CommonAPI do
local: true
)} do
{:ok, activity}
+ else
+ {:common_pipeline, {:reject, _} = e} -> e
+ e -> e
end
end
diff --git a/lib/pleroma/web/pleroma_api/controllers/chat_controller.ex b/lib/pleroma/web/pleroma_api/controllers/chat_controller.ex
index 1f2e953f7..ea0921c77 100644
--- a/lib/pleroma/web/pleroma_api/controllers/chat_controller.ex
+++ b/lib/pleroma/web/pleroma_api/controllers/chat_controller.ex
@@ -90,6 +90,16 @@ defmodule Pleroma.Web.PleromaAPI.ChatController do
conn
|> put_view(MessageReferenceView)
|> render("show.json", chat_message_reference: cm_ref)
+ else
+ {:reject, message} ->
+ conn
+ |> put_status(:unprocessable_entity)
+ |> json(%{error: message})
+
+ {:error, message} ->
+ conn
+ |> put_status(:bad_request)
+ |> json(%{error: message})
end
end