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_USE_TLS: true
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]
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 """
if model: # a bonus check we can do if we already know the model
result = model.find_existing_by_remote_id(remote_id)
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
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
result = model.find_existing(data)
if result and not refresh:
return result
return result if not get_activity else result.to_activity_dataclass()
item = model.activity_serializer(**data)
if get_activity:
return item
# if we're refreshing, "result" will be set and we'll update it
return item.to_model(model=model, instance=result, save=save)

View file

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

View file

@ -123,12 +123,14 @@ class Status(OrderedCollectionPageMixin, BookWyrmModel):
""" keep notes if they are replies to existing statuses """
if activity.type == "Announce":
try:
boosted = activitypub.resolve_remote_id(activity.object, save=False)
boosted = activitypub.resolve_remote_id(
activity.object, get_activity=True
)
except activitypub.ActivitySerializerError:
# if we can't load the status, definitely ignore it
return True
# 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
if activity.type != "Note":
@ -375,7 +377,7 @@ class Boost(ActivityMixin, Status):
""" the user field is "actor" here instead of "attributedTo" """
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.activity_fields = self.simple_fields
self.many_to_many_fields = []

View file

@ -441,6 +441,9 @@ class Status(TestCase):
id="http://www.faraway.com/boost/12",
actor=self.remote_user.remote_id,
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)

View file

@ -559,6 +559,9 @@ class Inbox(TestCase):
"id": "%s/boost" % self.status.remote_id,
"actor": self.remote_user.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:
discarder.return_value = False
@ -607,6 +610,9 @@ class Inbox(TestCase):
"id": boost.remote_id,
"actor": self.remote_user.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(
@ -614,6 +620,7 @@ class Inbox(TestCase):
) as redis_mock:
views.inbox.activity_task(activity)
self.assertTrue(redis_mock.called)
self.assertFalse(models.Boost.objects.exists())
def test_handle_unboost_unknown_boost(self):
""" undo a boost """