Merge pull request #795 from mouse-reeve/boost-federation

Fixes ignore filter for valid remote statuses
This commit is contained in:
Mouse Reeve 2021-03-25 06:43:27 -07:00 committed by GitHub
commit 7263c9fd63
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 28 additions and 8 deletions

View file

@ -65,4 +65,4 @@ jobs:
EMAIL_HOST_PASSWORD: "" EMAIL_HOST_PASSWORD: ""
EMAIL_USE_TLS: true EMAIL_USE_TLS: true
run: | run: |
python manage.py test -v 3 python manage.py test

View file

@ -248,12 +248,14 @@ def get_model_from_type(activity_type):
return model[0] return model[0]
def resolve_remote_id(remote_id, model=None, refresh=False, save=True): def resolve_remote_id(
remote_id, model=None, refresh=False, save=True, get_activity=False
):
""" take a remote_id and return an instance, creating if necessary """ """ take a remote_id and return an instance, creating if necessary """
if model: # a bonus check we can do if we already know the model if model: # a bonus check we can do if we already know the model
result = model.find_existing_by_remote_id(remote_id) result = model.find_existing_by_remote_id(remote_id)
if result and not refresh: if result and not refresh:
return result return result if not get_activity else result.to_activity_dataclass()
# load the data and create the object # load the data and create the object
try: try:
@ -269,8 +271,11 @@ def resolve_remote_id(remote_id, model=None, refresh=False, save=True):
# check for existing items with shared unique identifiers # check for existing items with shared unique identifiers
result = model.find_existing(data) result = model.find_existing(data)
if result and not refresh: if result and not refresh:
return result return result if not get_activity else result.to_activity_dataclass()
item = model.activity_serializer(**data) item = model.activity_serializer(**data)
if get_activity:
return item
# if we're refreshing, "result" will be set and we'll update it # if we're refreshing, "result" will be set and we'll update it
return item.to_model(model=model, instance=result, save=save) return item.to_model(model=model, instance=result, save=save)

View file

@ -1,5 +1,5 @@
""" undo wrapper activity """ """ undo wrapper activity """
from dataclasses import dataclass from dataclasses import dataclass, field
from typing import List from typing import List
from django.apps import apps from django.apps import apps
@ -191,6 +191,9 @@ class Like(Verb):
class Announce(Verb): class Announce(Verb):
""" boosting a status """ """ boosting a status """
published: str
to: List[str] = field(default_factory=lambda: [])
cc: List[str] = field(default_factory=lambda: [])
object: str object: str
type: str = "Announce" type: str = "Announce"

View file

@ -123,12 +123,14 @@ class Status(OrderedCollectionPageMixin, BookWyrmModel):
""" keep notes if they are replies to existing statuses """ """ keep notes if they are replies to existing statuses """
if activity.type == "Announce": if activity.type == "Announce":
try: try:
boosted = activitypub.resolve_remote_id(activity.object, save=False) boosted = activitypub.resolve_remote_id(
activity.object, get_activity=True
)
except activitypub.ActivitySerializerError: except activitypub.ActivitySerializerError:
# if we can't load the status, definitely ignore it # if we can't load the status, definitely ignore it
return True return True
# keep the boost if we would keep the status # keep the boost if we would keep the status
return cls.ignore_activity(boosted.to_activity_dataclass()) return cls.ignore_activity(boosted)
# keep if it if it's a custom type # keep if it if it's a custom type
if activity.type != "Note": if activity.type != "Note":
@ -375,7 +377,7 @@ class Boost(ActivityMixin, Status):
""" the user field is "actor" here instead of "attributedTo" """ """ the user field is "actor" here instead of "attributedTo" """
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
reserve_fields = ["user", "boosted_status"] reserve_fields = ["user", "boosted_status", "published_date", "privacy"]
self.simple_fields = [f for f in self.simple_fields if f.name in reserve_fields] self.simple_fields = [f for f in self.simple_fields if f.name in reserve_fields]
self.activity_fields = self.simple_fields self.activity_fields = self.simple_fields
self.many_to_many_fields = [] self.many_to_many_fields = []

View file

@ -441,6 +441,9 @@ class Status(TestCase):
id="http://www.faraway.com/boost/12", id="http://www.faraway.com/boost/12",
actor=self.remote_user.remote_id, actor=self.remote_user.remote_id,
object="http://fish.com/nothing", object="http://fish.com/nothing",
published="2021-03-24T18:59:41.841208+00:00",
cc="",
to="",
) )
responses.add(responses.GET, "http://fish.com/nothing", status=404) responses.add(responses.GET, "http://fish.com/nothing", status=404)

View file

@ -559,6 +559,9 @@ class Inbox(TestCase):
"id": "%s/boost" % self.status.remote_id, "id": "%s/boost" % self.status.remote_id,
"actor": self.remote_user.remote_id, "actor": self.remote_user.remote_id,
"object": self.status.remote_id, "object": self.status.remote_id,
"to": ["https://www.w3.org/ns/activitystreams#public"],
"cc": ["https://example.com/user/mouse/followers"],
"published": "Mon, 25 May 2020 19:31:20 GMT",
} }
with patch("bookwyrm.models.status.Status.ignore_activity") as discarder: with patch("bookwyrm.models.status.Status.ignore_activity") as discarder:
discarder.return_value = False discarder.return_value = False
@ -607,6 +610,9 @@ class Inbox(TestCase):
"id": boost.remote_id, "id": boost.remote_id,
"actor": self.remote_user.remote_id, "actor": self.remote_user.remote_id,
"object": self.status.remote_id, "object": self.status.remote_id,
"to": ["https://www.w3.org/ns/activitystreams#public"],
"cc": ["https://example.com/user/mouse/followers"],
"published": "Mon, 25 May 2020 19:31:20 GMT",
}, },
} }
with patch( with patch(
@ -614,6 +620,7 @@ class Inbox(TestCase):
) as redis_mock: ) as redis_mock:
views.inbox.activity_task(activity) views.inbox.activity_task(activity)
self.assertTrue(redis_mock.called) self.assertTrue(redis_mock.called)
self.assertFalse(models.Boost.objects.exists())
def test_handle_unboost_unknown_boost(self): def test_handle_unboost_unknown_boost(self):
""" undo a boost """ """ undo a boost """