forked from YokaiRick/akkoma
Create MRF.filter_pipeline to inject :object_data when present
This commit is contained in:
parent
3a0f99ed35
commit
abf25e5d52
6 changed files with 59 additions and 15 deletions
|
@ -27,6 +27,12 @@ switched to a new configuration mechanism, however it was not officially removed
|
||||||
- Welcome Chat messages preventing user registration with MRF Simple Policy applied to the local instance
|
- Welcome Chat messages preventing user registration with MRF Simple Policy applied to the local instance
|
||||||
- Mastodon API: the public timeline returning an error when the `reply_visibility` parameter is set to `self` for an unauthenticated user
|
- Mastodon API: the public timeline returning an error when the `reply_visibility` parameter is set to `self` for an unauthenticated user
|
||||||
|
|
||||||
|
## Unreleased-patch
|
||||||
|
|
||||||
|
### Security
|
||||||
|
|
||||||
|
- Fix most MRF rules either crashing or not being applied to objects passed into the Common Pipeline (ChatMessage, Question, Answer, Audio, Event)
|
||||||
|
|
||||||
## [2.1.1] - 2020-09-08
|
## [2.1.1] - 2020-09-08
|
||||||
|
|
||||||
### Security
|
### Security
|
||||||
|
|
|
@ -5,16 +5,34 @@
|
||||||
defmodule Pleroma.Web.ActivityPub.MRF do
|
defmodule Pleroma.Web.ActivityPub.MRF do
|
||||||
@callback filter(Map.t()) :: {:ok | :reject, Map.t()}
|
@callback filter(Map.t()) :: {:ok | :reject, Map.t()}
|
||||||
|
|
||||||
def filter(policies, %{} = object) do
|
def filter(policies, %{} = message) do
|
||||||
policies
|
policies
|
||||||
|> Enum.reduce({:ok, object}, fn
|
|> Enum.reduce({:ok, message}, fn
|
||||||
policy, {:ok, object} -> policy.filter(object)
|
policy, {:ok, message} -> policy.filter(message)
|
||||||
_, error -> error
|
_, error -> error
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
def filter(%{} = object), do: get_policies() |> filter(object)
|
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
|
def get_policies do
|
||||||
Pleroma.Config.get([:mrf, :policies], []) |> get_policies()
|
Pleroma.Config.get([:mrf, :policies], []) |> get_policies()
|
||||||
end
|
end
|
||||||
|
|
|
@ -28,8 +28,7 @@ def filter(%{"actor" => actor} = message) do
|
||||||
}"
|
}"
|
||||||
)
|
)
|
||||||
|
|
||||||
subchain
|
MRF.filter(subchain, message)
|
||||||
|> MRF.filter(message)
|
|
||||||
else
|
else
|
||||||
_e -> {:ok, message}
|
_e -> {:ok, message}
|
||||||
end
|
end
|
||||||
|
|
|
@ -26,13 +26,17 @@ def common_pipeline(object, meta) do
|
||||||
|
|
||||||
{:error, e} ->
|
{:error, e} ->
|
||||||
{:error, e}
|
{:error, e}
|
||||||
|
|
||||||
|
{:reject, e} ->
|
||||||
|
{:reject, e}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def do_common_pipeline(object, meta) do
|
def do_common_pipeline(object, meta) do
|
||||||
with {_, {:ok, validated_object, meta}} <-
|
with {_, {:ok, validated_object, meta}} <-
|
||||||
{:validate_object, ObjectValidator.validate(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}} <-
|
{_, {:ok, activity, meta}} <-
|
||||||
{:persist_object, ActivityPub.persist(mrfd_object, meta)},
|
{:persist_object, ActivityPub.persist(mrfd_object, meta)},
|
||||||
{_, {:ok, activity, meta}} <-
|
{_, {:ok, activity, meta}} <-
|
||||||
|
@ -40,7 +44,7 @@ def do_common_pipeline(object, meta) do
|
||||||
{_, {:ok, _}} <- {:federation, maybe_federate(activity, meta)} do
|
{_, {:ok, _}} <- {:federation, maybe_federate(activity, meta)} do
|
||||||
{:ok, activity, meta}
|
{:ok, activity, meta}
|
||||||
else
|
else
|
||||||
{:mrf_object, {:reject, _}} -> {:ok, nil, meta}
|
{:mrf_object, {:reject, message, _}} -> {:reject, message}
|
||||||
e -> {:error, e}
|
e -> {:error, e}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -26,7 +26,7 @@ test "when given an `object_data` in meta, Federation will receive a the origina
|
||||||
{
|
{
|
||||||
Pleroma.Web.ActivityPub.MRF,
|
Pleroma.Web.ActivityPub.MRF,
|
||||||
[],
|
[],
|
||||||
[filter: fn o -> {:ok, o} end]
|
[pipeline_filter: fn o, m -> {:ok, o, m} end]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Pleroma.Web.ActivityPub.ActivityPub,
|
Pleroma.Web.ActivityPub.ActivityPub,
|
||||||
|
@ -51,7 +51,7 @@ test "when given an `object_data` in meta, Federation will receive a the origina
|
||||||
Pleroma.Web.ActivityPub.Pipeline.common_pipeline(activity, meta)
|
Pleroma.Web.ActivityPub.Pipeline.common_pipeline(activity, meta)
|
||||||
|
|
||||||
assert_called(Pleroma.Web.ActivityPub.ObjectValidator.validate(activity, meta))
|
assert_called(Pleroma.Web.ActivityPub.ObjectValidator.validate(activity, meta))
|
||||||
assert_called(Pleroma.Web.ActivityPub.MRF.filter(activity))
|
assert_called(Pleroma.Web.ActivityPub.MRF.pipeline_filter(activity, meta))
|
||||||
assert_called(Pleroma.Web.ActivityPub.ActivityPub.persist(activity, meta))
|
assert_called(Pleroma.Web.ActivityPub.ActivityPub.persist(activity, meta))
|
||||||
assert_called(Pleroma.Web.ActivityPub.SideEffects.handle(activity, meta))
|
assert_called(Pleroma.Web.ActivityPub.SideEffects.handle(activity, meta))
|
||||||
refute called(Pleroma.Web.Federator.publish(activity))
|
refute called(Pleroma.Web.Federator.publish(activity))
|
||||||
|
@ -68,7 +68,7 @@ test "it goes through validation, filtering, persisting, side effects and federa
|
||||||
{
|
{
|
||||||
Pleroma.Web.ActivityPub.MRF,
|
Pleroma.Web.ActivityPub.MRF,
|
||||||
[],
|
[],
|
||||||
[filter: fn o -> {:ok, o} end]
|
[pipeline_filter: fn o, m -> {:ok, o, m} end]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Pleroma.Web.ActivityPub.ActivityPub,
|
Pleroma.Web.ActivityPub.ActivityPub,
|
||||||
|
@ -93,7 +93,7 @@ test "it goes through validation, filtering, persisting, side effects and federa
|
||||||
Pleroma.Web.ActivityPub.Pipeline.common_pipeline(activity, meta)
|
Pleroma.Web.ActivityPub.Pipeline.common_pipeline(activity, meta)
|
||||||
|
|
||||||
assert_called(Pleroma.Web.ActivityPub.ObjectValidator.validate(activity, meta))
|
assert_called(Pleroma.Web.ActivityPub.ObjectValidator.validate(activity, meta))
|
||||||
assert_called(Pleroma.Web.ActivityPub.MRF.filter(activity))
|
assert_called(Pleroma.Web.ActivityPub.MRF.pipeline_filter(activity, meta))
|
||||||
assert_called(Pleroma.Web.ActivityPub.ActivityPub.persist(activity, meta))
|
assert_called(Pleroma.Web.ActivityPub.ActivityPub.persist(activity, meta))
|
||||||
assert_called(Pleroma.Web.ActivityPub.SideEffects.handle(activity, meta))
|
assert_called(Pleroma.Web.ActivityPub.SideEffects.handle(activity, meta))
|
||||||
assert_called(Pleroma.Web.Federator.publish(activity))
|
assert_called(Pleroma.Web.Federator.publish(activity))
|
||||||
|
@ -109,7 +109,7 @@ test "it goes through validation, filtering, persisting, side effects without fe
|
||||||
{
|
{
|
||||||
Pleroma.Web.ActivityPub.MRF,
|
Pleroma.Web.ActivityPub.MRF,
|
||||||
[],
|
[],
|
||||||
[filter: fn o -> {:ok, o} end]
|
[pipeline_filter: fn o, m -> {:ok, o, m} end]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Pleroma.Web.ActivityPub.ActivityPub,
|
Pleroma.Web.ActivityPub.ActivityPub,
|
||||||
|
@ -131,7 +131,7 @@ test "it goes through validation, filtering, persisting, side effects without fe
|
||||||
Pleroma.Web.ActivityPub.Pipeline.common_pipeline(activity, meta)
|
Pleroma.Web.ActivityPub.Pipeline.common_pipeline(activity, meta)
|
||||||
|
|
||||||
assert_called(Pleroma.Web.ActivityPub.ObjectValidator.validate(activity, meta))
|
assert_called(Pleroma.Web.ActivityPub.ObjectValidator.validate(activity, meta))
|
||||||
assert_called(Pleroma.Web.ActivityPub.MRF.filter(activity))
|
assert_called(Pleroma.Web.ActivityPub.MRF.pipeline_filter(activity, meta))
|
||||||
assert_called(Pleroma.Web.ActivityPub.ActivityPub.persist(activity, meta))
|
assert_called(Pleroma.Web.ActivityPub.ActivityPub.persist(activity, meta))
|
||||||
assert_called(Pleroma.Web.ActivityPub.SideEffects.handle(activity, meta))
|
assert_called(Pleroma.Web.ActivityPub.SideEffects.handle(activity, meta))
|
||||||
end
|
end
|
||||||
|
@ -148,7 +148,7 @@ test "it goes through validation, filtering, persisting, side effects without fe
|
||||||
{
|
{
|
||||||
Pleroma.Web.ActivityPub.MRF,
|
Pleroma.Web.ActivityPub.MRF,
|
||||||
[],
|
[],
|
||||||
[filter: fn o -> {:ok, o} end]
|
[pipeline_filter: fn o, m -> {:ok, o, m} end]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Pleroma.Web.ActivityPub.ActivityPub,
|
Pleroma.Web.ActivityPub.ActivityPub,
|
||||||
|
@ -170,7 +170,7 @@ test "it goes through validation, filtering, persisting, side effects without fe
|
||||||
Pleroma.Web.ActivityPub.Pipeline.common_pipeline(activity, meta)
|
Pleroma.Web.ActivityPub.Pipeline.common_pipeline(activity, meta)
|
||||||
|
|
||||||
assert_called(Pleroma.Web.ActivityPub.ObjectValidator.validate(activity, meta))
|
assert_called(Pleroma.Web.ActivityPub.ObjectValidator.validate(activity, meta))
|
||||||
assert_called(Pleroma.Web.ActivityPub.MRF.filter(activity))
|
assert_called(Pleroma.Web.ActivityPub.MRF.pipeline_filter(activity, meta))
|
||||||
assert_called(Pleroma.Web.ActivityPub.ActivityPub.persist(activity, meta))
|
assert_called(Pleroma.Web.ActivityPub.ActivityPub.persist(activity, meta))
|
||||||
assert_called(Pleroma.Web.ActivityPub.SideEffects.handle(activity, meta))
|
assert_called(Pleroma.Web.ActivityPub.SideEffects.handle(activity, meta))
|
||||||
end
|
end
|
||||||
|
|
|
@ -126,6 +126,23 @@ test "it works with an attachment", %{conn: conn, user: user} do
|
||||||
|
|
||||||
assert result["attachment"]
|
assert result["attachment"]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "gets MRF reason when rejected", %{conn: conn, user: user} do
|
||||||
|
clear_config([:mrf_keyword, :reject], ["GNO"])
|
||||||
|
clear_config([:mrf, :policies], [Pleroma.Web.ActivityPub.MRF.KeywordPolicy])
|
||||||
|
|
||||||
|
other_user = insert(:user)
|
||||||
|
|
||||||
|
{:ok, chat} = Chat.get_or_create(user.id, other_user.ap_id)
|
||||||
|
|
||||||
|
result =
|
||||||
|
conn
|
||||||
|
|> put_req_header("content-type", "application/json")
|
||||||
|
|> post("/api/v1/pleroma/chats/#{chat.id}/messages", %{"content" => "GNO/Linux"})
|
||||||
|
|> json_response_and_validate_schema(200)
|
||||||
|
|
||||||
|
assert result == %{}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "DELETE /api/v1/pleroma/chats/:id/messages/:message_id" do
|
describe "DELETE /api/v1/pleroma/chats/:id/messages/:message_id" do
|
||||||
|
|
Loading…
Reference in a new issue