kopia lustrzana https://dev.funkwhale.audio/funkwhale/funkwhale
Test bot can now unfollow
rodzic
81e7f03f77
commit
3ad1fe17d5
|
@ -130,7 +130,7 @@ class SystemActor(object):
|
|||
'No handler for activity %s', ac['type'])
|
||||
return
|
||||
|
||||
return handler(ac, actor)
|
||||
return handler(data, actor)
|
||||
|
||||
|
||||
class LibraryActor(SystemActor):
|
||||
|
@ -269,6 +269,40 @@ class TestActor(SystemActor):
|
|||
to=[ac['actor']],
|
||||
on_behalf_of=test_actor)
|
||||
|
||||
def handle_undo(self, ac, sender):
|
||||
if ac['object']['type'] != 'Follow':
|
||||
return
|
||||
|
||||
if ac['object']['actor'] != sender.url:
|
||||
# not the same actor, permission issue
|
||||
return
|
||||
|
||||
test_actor = self.get_actor_instance()
|
||||
models.Follow.objects.filter(
|
||||
actor=sender,
|
||||
target=test_actor,
|
||||
).delete()
|
||||
# we also unfollow the sender, if possible
|
||||
try:
|
||||
follow = models.Follow.objects.get(
|
||||
target=sender,
|
||||
actor=test_actor,
|
||||
)
|
||||
except models.Follow.DoesNotExist:
|
||||
return
|
||||
undo = {
|
||||
'@context': serializers.AP_CONTEXT,
|
||||
'type': 'Undo',
|
||||
'id': follow.get_federation_url() + '/undo',
|
||||
'actor': test_actor.url,
|
||||
'object': serializers.FollowSerializer(follow).data,
|
||||
}
|
||||
follow.delete()
|
||||
activity.deliver(
|
||||
undo,
|
||||
to=[sender.url],
|
||||
on_behalf_of=test_actor)
|
||||
|
||||
SYSTEM_ACTORS = {
|
||||
'library': LibraryActor(),
|
||||
'test': TestActor(),
|
||||
|
|
|
@ -3,6 +3,7 @@ import requests
|
|||
import requests_http_signature
|
||||
|
||||
from django.utils import timezone
|
||||
from django.conf import settings
|
||||
|
||||
from funkwhale_api.factories import registry
|
||||
|
||||
|
@ -65,6 +66,12 @@ class ActorFactory(factory.DjangoModelFactory):
|
|||
class Meta:
|
||||
model = models.Actor
|
||||
|
||||
class Params:
|
||||
local = factory.Trait(
|
||||
domain=factory.LazyAttribute(
|
||||
lambda o: settings.FEDERATION_HOSTNAME)
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def _generate(cls, create, attrs):
|
||||
has_public = attrs.get('public_key') is not None
|
||||
|
@ -84,6 +91,11 @@ class FollowFactory(factory.DjangoModelFactory):
|
|||
class Meta:
|
||||
model = models.Follow
|
||||
|
||||
class Params:
|
||||
local = factory.Trait(
|
||||
actor=factory.SubFactory(ActorFactory, local=True)
|
||||
)
|
||||
|
||||
|
||||
@registry.register(name='federation.Note')
|
||||
class NoteFactory(factory.Factory):
|
||||
|
|
|
@ -14,6 +14,8 @@ TYPE_CHOICES = [
|
|||
|
||||
|
||||
class Actor(models.Model):
|
||||
ap_type = 'Actor'
|
||||
|
||||
url = models.URLField(unique=True, max_length=500, db_index=True)
|
||||
outbox_url = models.URLField(max_length=500)
|
||||
inbox_url = models.URLField(max_length=500)
|
||||
|
@ -79,6 +81,8 @@ class Actor(models.Model):
|
|||
|
||||
|
||||
class Follow(models.Model):
|
||||
ap_type = 'Follow'
|
||||
|
||||
uuid = models.UUIDField(default=uuid.uuid4, unique=True)
|
||||
actor = models.ForeignKey(
|
||||
Actor,
|
||||
|
@ -96,3 +100,6 @@ class Follow(models.Model):
|
|||
|
||||
class Meta:
|
||||
unique_together = ['actor', 'target']
|
||||
|
||||
def get_federation_url(self):
|
||||
return '{}#follows/{}'.format(self.actor.url, self.uuid)
|
||||
|
|
|
@ -169,11 +169,7 @@ def test_test_post_inbox_handles_create_note(
|
|||
}]
|
||||
)
|
||||
expected_activity = {
|
||||
'@context': [
|
||||
'https://www.w3.org/ns/activitystreams',
|
||||
'https://w3id.org/security/v1',
|
||||
{}
|
||||
],
|
||||
'@context': serializers.AP_CONTEXT,
|
||||
'actor': test_actor.url,
|
||||
'id': 'https://{}/activities/note/{}/activity'.format(
|
||||
settings.FEDERATION_HOSTNAME, now.timestamp()
|
||||
|
@ -288,11 +284,7 @@ def test_test_actor_handles_follow(
|
|||
},
|
||||
}
|
||||
expected_follow = {
|
||||
'@context': [
|
||||
'https://www.w3.org/ns/activitystreams',
|
||||
'https://w3id.org/security/v1',
|
||||
{}
|
||||
],
|
||||
'@context': serializers.AP_CONTEXT,
|
||||
'actor': test_actor.url,
|
||||
'id': test_actor.url + '#follows/{}'.format(uid),
|
||||
'object': actor.url,
|
||||
|
@ -317,3 +309,38 @@ def test_test_actor_handles_follow(
|
|||
follow = test_actor.received_follows.first()
|
||||
assert follow.actor == actor
|
||||
assert follow.target == test_actor
|
||||
|
||||
|
||||
def test_test_actor_handles_undo_follow(
|
||||
settings, mocker, factories):
|
||||
deliver = mocker.patch(
|
||||
'funkwhale_api.federation.activity.deliver')
|
||||
test_actor = actors.SYSTEM_ACTORS['test'].get_actor_instance()
|
||||
follow = factories['federation.Follow'](target=test_actor)
|
||||
reverse_follow = factories['federation.Follow'](
|
||||
actor=test_actor, target=follow.actor)
|
||||
follow_serializer = serializers.FollowSerializer(follow)
|
||||
reverse_follow_serializer = serializers.FollowSerializer(
|
||||
reverse_follow)
|
||||
undo = {
|
||||
'@context': serializers.AP_CONTEXT,
|
||||
'type': 'Undo',
|
||||
'id': follow_serializer.data['id'] + '/undo',
|
||||
'actor': follow.actor.url,
|
||||
'object': follow_serializer.data,
|
||||
}
|
||||
expected_undo = {
|
||||
'@context': serializers.AP_CONTEXT,
|
||||
'type': 'Undo',
|
||||
'id': reverse_follow_serializer.data['id'] + '/undo',
|
||||
'actor': reverse_follow.actor.url,
|
||||
'object': reverse_follow_serializer.data,
|
||||
}
|
||||
|
||||
actors.SYSTEM_ACTORS['test'].post_inbox(undo, actor=follow.actor)
|
||||
deliver.assert_called_once_with(
|
||||
expected_undo,
|
||||
to=[follow.actor.url],
|
||||
on_behalf_of=test_actor,)
|
||||
|
||||
assert models.Follow.objects.count() == 0
|
||||
|
|
|
@ -3,7 +3,7 @@ from funkwhale_api.federation import keys
|
|||
from funkwhale_api.federation import signing
|
||||
|
||||
|
||||
def test_authenticate(nodb_factories, mocker, api_request):
|
||||
def test_authenticate(factories, mocker, api_request):
|
||||
private, public = keys.get_key_pair()
|
||||
actor_url = 'https://test.federation/actor'
|
||||
mocker.patch(
|
||||
|
@ -18,7 +18,7 @@ def test_authenticate(nodb_factories, mocker, api_request):
|
|||
'id': actor_url + '#main-key',
|
||||
}
|
||||
})
|
||||
signed_request = nodb_factories['federation.SignedRequest'](
|
||||
signed_request = factories['federation.SignedRequest'](
|
||||
auth__key=private,
|
||||
auth__key_id=actor_url + '#main-key',
|
||||
auth__headers=[
|
||||
|
|
|
@ -23,3 +23,10 @@ def test_cannot_duplicate_follow(factories):
|
|||
target=follow.target,
|
||||
actor=follow.actor,
|
||||
)
|
||||
|
||||
def test_follow_federation_url(factories):
|
||||
follow = factories['federation.Follow'](local=True)
|
||||
expected = '{}#follows/{}'.format(
|
||||
follow.actor.url, follow.uuid)
|
||||
|
||||
assert follow.get_federation_url() == expected
|
||||
|
|
Ładowanie…
Reference in New Issue