Merge branch 'feature/fake-statuses' into 'develop'

Add fake status submit

See merge request pleroma/pleroma!995
This commit is contained in:
lambda 2019-04-02 14:17:43 +00:00
commit a79ce94dd4
7 changed files with 141 additions and 27 deletions

View File

@ -44,3 +44,9 @@ Has these additional fields under the `pleroma` object:
Has these additional fields under the `pleroma` object:
- `is_seen`: true if the notification was read by the user
## POST `/api/v1/statuses`
Additional parameters can be added to the JSON body:
- `preview`: boolean, if set to `true` the post won't be actually posted, but the status entitiy would still be rendered back. This could be useful for previewing rich text/custom emoji, for example.

View File

@ -28,9 +28,13 @@ def filter_tags(html, scrubber), do: Scrubber.scrub(html, scrubber)
def filter_tags(html), do: filter_tags(html, nil)
def strip_tags(html), do: Scrubber.scrub(html, Scrubber.StripTags)
# TODO: rename object to activity because that's what it is really working with
def get_cached_scrubbed_html_for_object(content, scrubbers, object, module) do
key = "#{module}#{generate_scrubber_signature(scrubbers)}|#{object.id}"
Cachex.fetch!(:scrubber_cache, key, fn _key -> ensure_scrubbed_html(content, scrubbers) end)
Cachex.fetch!(:scrubber_cache, key, fn _key ->
ensure_scrubbed_html(content, scrubbers, object.data["object"]["fake"] || false)
end)
end
def get_cached_stripped_html_for_object(content, object, module) do
@ -44,11 +48,20 @@ def get_cached_stripped_html_for_object(content, object, module) do
def ensure_scrubbed_html(
content,
scrubbers
scrubbers,
false = _fake
) do
{:commit, filter_tags(content, scrubbers)}
end
def ensure_scrubbed_html(
content,
scrubbers,
true = _fake
) do
{:ignore, filter_tags(content, scrubbers)}
end
defp generate_scrubber_signature(scrubber) when is_atom(scrubber) do
generate_scrubber_signature([scrubber])
end

View File

@ -44,6 +44,11 @@ def get_by_ap_id(ap_id) do
# Use this whenever possible, especially when walking graphs in an O(N) loop!
def normalize(%Activity{object: %Object{} = object}), do: object
# A hack for fake activities
def normalize(%Activity{data: %{"object" => %{"fake" => true} = data}}) do
%Object{id: "pleroma:fake_object_id", data: data}
end
# Catch and log Object.normalize() calls where the Activity's child object is not
# preloaded.
def normalize(%Activity{data: %{"object" => %{"id" => ap_id}}}) do

View File

@ -113,15 +113,15 @@ def decrease_replies_count_if_reply(%Object{
def decrease_replies_count_if_reply(_object), do: :noop
def insert(map, local \\ true) when is_map(map) do
def insert(map, local \\ true, fake \\ false) when is_map(map) do
with nil <- Activity.normalize(map),
map <- lazy_put_activity_defaults(map),
map <- lazy_put_activity_defaults(map, fake),
:ok <- check_actor_is_active(map["actor"]),
{_, true} <- {:remote_limit_error, check_remote_limit(map)},
{:ok, map} <- MRF.filter(map),
{recipients, _, _} = get_recipients(map),
{:fake, false, map, recipients} <- {:fake, fake, map, recipients},
{:ok, object} <- insert_full_object(map) do
{recipients, _, _} = get_recipients(map)
{:ok, activity} =
Repo.insert(%Activity{
data: map,
@ -146,8 +146,23 @@ def insert(map, local \\ true) when is_map(map) do
stream_out(activity)
{:ok, activity}
else
%Activity{} = activity -> {:ok, activity}
error -> {:error, error}
%Activity{} = activity ->
{:ok, activity}
{:fake, true, map, recipients} ->
activity = %Activity{
data: map,
local: local,
actor: map["actor"],
recipients: recipients,
id: "pleroma:fakeid"
}
Pleroma.Web.RichMedia.Helpers.fetch_data_for_activity(activity)
{:ok, activity}
error ->
{:error, error}
end
end
@ -190,7 +205,7 @@ def stream_out(activity) do
end
end
def create(%{to: to, actor: actor, context: context, object: object} = params) do
def create(%{to: to, actor: actor, context: context, object: object} = params, fake \\ false) do
additional = params[:additional] || %{}
# only accept false as false value
local = !(params[:local] == false)
@ -201,13 +216,17 @@ def create(%{to: to, actor: actor, context: context, object: object} = params) d
%{to: to, actor: actor, published: published, context: context, object: object},
additional
),
{:ok, activity} <- insert(create_data, local),
{:ok, activity} <- insert(create_data, local, fake),
{:fake, false, activity} <- {:fake, fake, activity},
_ <- increase_replies_count_if_reply(create_data),
# Changing note count prior to enqueuing federation task in order to avoid
# race conditions on updating user.info
{:ok, _actor} <- increase_note_count_if_public(actor, activity),
:ok <- maybe_federate(activity) do
{:ok, activity}
else
{:fake, true, activity} ->
{:ok, activity}
end
end

View File

@ -175,18 +175,26 @@ def maybe_federate(_), do: :ok
Adds an id and a published data if they aren't there,
also adds it to an included object
"""
def lazy_put_activity_defaults(map) do
def lazy_put_activity_defaults(map, fake \\ false) do
map =
unless fake do
%{data: %{"id" => context}, id: context_id} = create_context(map["context"])
map =
map
|> Map.put_new_lazy("id", &generate_activity_id/0)
|> Map.put_new_lazy("published", &make_date/0)
|> Map.put_new("context", context)
|> Map.put_new("context_id", context_id)
else
map
|> Map.put_new("id", "pleroma:fakeid")
|> Map.put_new_lazy("published", &make_date/0)
|> Map.put_new("context", "pleroma:fakecontext")
|> Map.put_new("context_id", -1)
end
if is_map(map["object"]) do
object = lazy_put_object_defaults(map["object"], map)
object = lazy_put_object_defaults(map["object"], map, fake)
%{map | "object" => object}
else
map
@ -196,7 +204,18 @@ def lazy_put_activity_defaults(map) do
@doc """
Adds an id and published date if they aren't there.
"""
def lazy_put_object_defaults(map, activity \\ %{}) do
def lazy_put_object_defaults(map, activity \\ %{}, fake)
def lazy_put_object_defaults(map, activity, true = _fake) do
map
|> Map.put_new_lazy("published", &make_date/0)
|> Map.put_new("id", "pleroma:fake_object_id")
|> Map.put_new("context", activity["context"])
|> Map.put_new("fake", true)
|> Map.put_new("context_id", activity["context_id"])
end
def lazy_put_object_defaults(map, activity, _fake) do
map
|> Map.put_new_lazy("id", &generate_object_id/0)
|> Map.put_new_lazy("published", &make_date/0)

View File

@ -172,13 +172,16 @@ def post(user, %{"status" => status} = data) do
end)
) do
res =
ActivityPub.create(%{
ActivityPub.create(
%{
to: to,
actor: user,
context: context,
object: object,
additional: %{"cc" => cc, "directMessage" => visibility == "direct"}
})
},
data["preview"] || false
)
res
end

View File

@ -143,6 +143,55 @@ test "posting a sensitive status", %{conn: conn} do
assert Activity.get_by_id(id)
end
test "posting a fake status", %{conn: conn} do
user = insert(:user)
real_conn =
conn
|> assign(:user, user)
|> post("/api/v1/statuses", %{
"status" =>
"\"Tenshi Eating a Corndog\" is a much discussed concept on /jp/. The significance of it is disputed, so I will focus on one core concept: the symbolism behind it"
})
real_status = json_response(real_conn, 200)
assert real_status
assert Object.get_by_ap_id(real_status["uri"])
real_status =
real_status
|> Map.put("id", nil)
|> Map.put("url", nil)
|> Map.put("uri", nil)
|> Map.put("created_at", nil)
|> Kernel.put_in(["pleroma", "conversation_id"], nil)
fake_conn =
conn
|> assign(:user, user)
|> post("/api/v1/statuses", %{
"status" =>
"\"Tenshi Eating a Corndog\" is a much discussed concept on /jp/. The significance of it is disputed, so I will focus on one core concept: the symbolism behind it",
"preview" => true
})
fake_status = json_response(fake_conn, 200)
assert fake_status
refute Object.get_by_ap_id(fake_status["uri"])
fake_status =
fake_status
|> Map.put("id", nil)
|> Map.put("url", nil)
|> Map.put("uri", nil)
|> Map.put("created_at", nil)
|> Kernel.put_in(["pleroma", "conversation_id"], nil)
assert real_status == fake_status
end
test "posting a status with OGP link preview", %{conn: conn} do
Pleroma.Config.put([:rich_media, :enabled], true)
user = insert(:user)