mrf/object_age: fix handling of non-public objects
Some checks are pending
ci/woodpecker/pr/build-amd64 Pipeline is pending approval
ci/woodpecker/pr/build-arm64 Pipeline is pending approval
ci/woodpecker/pr/docs Pipeline is pending approval
ci/woodpecker/pr/lint Pipeline is pending approval
ci/woodpecker/pr/test Pipeline is pending approval
Some checks are pending
ci/woodpecker/pr/build-amd64 Pipeline is pending approval
ci/woodpecker/pr/build-arm64 Pipeline is pending approval
ci/woodpecker/pr/docs Pipeline is pending approval
ci/woodpecker/pr/lint Pipeline is pending approval
ci/woodpecker/pr/test Pipeline is pending approval
Currently logic unconditionally adds public adressing to "cc"
and follower adressing to "to" after attempting to strip it
from the other one. This is horrible for two reasons:
First the bug prompting this investigation and fix,
this creates duplicates when adressing URIs already
were in their intended final field; e.g. prominently
the case for all "unlisted" posts.
Since List.delete only removes the first occurence,
this then broke follower-adress stripping later on.
It’s also not safe in general wrt to non-public adressing:
e.g. pre-existing duplicates didn’t get fully stripped,
bespoke adressing modes with only one of public addressing
or follower addressing — and most importantly:
any belatedly received DM also got public adressing added!
Shockingly this last point was actually checked as "correct" in tests
albeit this appears to be a mistake from mindless match adjustments
from when genuine crashes on nil adressing lists got fixed in
10c792110e
.
Clean up this sloppy logic up, making sure all instances of relevant
adresses are purged and only readded when they actually existed to begin
with. To avoid problems with any List.delete usages remaining in other
places, also ensure we never create duplicate entries.
This commit is contained in:
parent
c0a99df06a
commit
5a3c6a6896
3 changed files with 29 additions and 9 deletions
|
@ -23,6 +23,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
- AP objects with additional JSON-LD profiles beyond ActivityStreams can now be fetched
|
||||
- Single-selection polls no longer expose the voter_count; MastoAPI demands it be null
|
||||
and this confused some clients leading to vote distributions >100%
|
||||
- ObjectAge policy no longer lets unlisted posts slip passed
|
||||
- ObjectAge policy no longer leaks belated DMs
|
||||
|
||||
## Changed
|
||||
- Refactored Rich Media to cache the content in the database. Fetching operations that could block status rendering have been eliminated.
|
||||
|
|
|
@ -34,16 +34,34 @@ defp check_reject(message, actions) do
|
|||
end
|
||||
end
|
||||
|
||||
@spec delete_and_count(list(), term()) :: {integer(), list()}
|
||||
defp delete_and_count(list, element), do: delete_and_count(list, element, {0, [], list})
|
||||
|
||||
defp delete_and_count([], _element, {0, _nlist, olist}), do: {0, olist}
|
||||
defp delete_and_count([], _element, {count, nlist, _olist}), do: {count, Enum.reverse(nlist)}
|
||||
|
||||
defp delete_and_count([h | r], h, {count, nlist, olist}),
|
||||
do: delete_and_count(r, h, {count + 1, nlist, olist})
|
||||
|
||||
defp delete_and_count([h | r], element, {count, nlist, olist}),
|
||||
do: delete_and_count(r, element, {count, [h | nlist], olist})
|
||||
|
||||
defp insert_if_needed(list, oldcount, element) do
|
||||
if oldcount <= 0 || Enum.member?(list, element) do
|
||||
list
|
||||
else
|
||||
[element | list]
|
||||
end
|
||||
end
|
||||
|
||||
defp check_delist(message, actions) do
|
||||
if :delist in actions do
|
||||
with %User{} = user <- User.get_cached_by_ap_id(message["actor"]) do
|
||||
to =
|
||||
List.delete(message["to"] || [], Pleroma.Constants.as_public()) ++
|
||||
[user.follower_address]
|
||||
{pubcnt, to} = delete_and_count(message["to"] || [], Pleroma.Constants.as_public())
|
||||
{flwcnt, cc} = delete_and_count(message["cc"] || [], user.follower_address)
|
||||
|
||||
cc =
|
||||
List.delete(message["cc"] || [], user.follower_address) ++
|
||||
[Pleroma.Constants.as_public()]
|
||||
cc = insert_if_needed(cc, pubcnt, Pleroma.Constants.as_public())
|
||||
to = insert_if_needed(to, flwcnt, user.follower_address)
|
||||
|
||||
message =
|
||||
message
|
||||
|
@ -65,8 +83,8 @@ defp check_delist(message, actions) do
|
|||
defp check_strip_followers(message, actions) do
|
||||
if :strip_followers in actions do
|
||||
with %User{} = user <- User.get_cached_by_ap_id(message["actor"]) do
|
||||
to = List.delete(message["to"] || [], user.follower_address)
|
||||
cc = List.delete(message["cc"] || [], user.follower_address)
|
||||
{_, to} = delete_and_count(message["to"] || [], user.follower_address)
|
||||
{_, cc} = delete_and_count(message["cc"] || [], user.follower_address)
|
||||
|
||||
message =
|
||||
message
|
||||
|
|
|
@ -79,7 +79,7 @@ test "works with objects with empty to or cc fields" do
|
|||
|
||||
{:ok, data} = ObjectAgePolicy.filter(data)
|
||||
|
||||
assert Visibility.get_visibility(%{data: data}) == "unlisted"
|
||||
assert Visibility.get_visibility(%{data: data}) == "direct"
|
||||
end
|
||||
|
||||
test "it delists an old post" do
|
||||
|
|
Loading…
Reference in a new issue