kopia lustrzana https://github.com/snarfed/bridgy-fed
extract new check_can_migrate_out method out of ActivityPub.migrate_out
for snarfed/bounce#40, snarfed/bounce#17pull/1999/head
rodzic
343cc0690a
commit
3be771a5b8
|
|
@ -540,25 +540,10 @@ class ActivityPub(User, Protocol):
|
|||
Raises:
|
||||
ValueError: eg if ``ActivityPub`` doesn't own ``to_user_id``
|
||||
"""
|
||||
def _error(msg):
|
||||
logger.warning(msg)
|
||||
raise ValueError(msg)
|
||||
|
||||
user_ap_id = user.id_as(cls)
|
||||
logger.info(f"Migrating {user.key.id()} 's bridged AP actor {user_ap_id} to {to_user_id}")
|
||||
|
||||
if cls.owns_id(to_user_id) is False:
|
||||
_error(f"{to_user_id} doesn't look like an {cls.LABEL} id")
|
||||
elif isinstance(user, cls):
|
||||
_error(f"{user.handle_or_id()} is on {cls.PHRASE}")
|
||||
elif not user.is_enabled(cls):
|
||||
_error(f"{user.handle_or_id()} isn't currently bridged to {cls.PHRASE}")
|
||||
|
||||
# check that the destination actor has an alias to the bridged actor
|
||||
to_actor = cls.load(to_user_id, remote=True)
|
||||
aka = util.get_list(to_actor.as2, 'alsoKnownAs')
|
||||
if user_ap_id not in aka:
|
||||
_error(f"{to_user_id} 's alsoKnownAs {aka} doesn't contain {user_ap_id}")
|
||||
cls.check_can_migrate_out(user, to_user_id)
|
||||
|
||||
# send a Move activity to all followers' inboxes
|
||||
id = f'{user_ap_id}#move-{to_user_id}'
|
||||
|
|
@ -582,6 +567,33 @@ class ActivityPub(User, Protocol):
|
|||
|
||||
return ret
|
||||
|
||||
@classmethod
|
||||
def check_can_migrate_out(cls, user, to_user_id):
|
||||
"""Raises an exception if a user can't yet migrate to a native AP account.
|
||||
|
||||
For example, if ``to_user_id`` isn't an ActivityPub actor id, or if it
|
||||
doesn't have ``user``'s bridged AP id in its ``alsoKnownAs``.
|
||||
|
||||
Args:
|
||||
user (models.User)
|
||||
to_user_id (str)
|
||||
|
||||
Raises:
|
||||
ValueError: if ``user`` can't migrate to ActivityPub or ``to_user_id`` yet
|
||||
"""
|
||||
super().check_can_migrate_out(user, to_user_id)
|
||||
|
||||
# check that the destination actor has an alias to the bridged actor
|
||||
if not (to_actor := cls.load(to_user_id, remote=True)):
|
||||
raise ValueError("Couldn't fetch {to_user_id}")
|
||||
|
||||
aka = util.get_list(to_actor.as2, 'alsoKnownAs')
|
||||
user_ap_id = user.id_as(cls)
|
||||
if user_ap_id not in aka:
|
||||
msg = f"{to_user_id} 's alsoKnownAs doesn't contain {user_ap_id}: {aka}"
|
||||
logger.warning(msg)
|
||||
raise ValueError(msg)
|
||||
|
||||
@classmethod
|
||||
def verify_signature(cls, activity):
|
||||
"""Verifies the current request's HTTP Signature.
|
||||
|
|
|
|||
30
protocol.py
30
protocol.py
|
|
@ -740,6 +740,36 @@ class Protocol:
|
|||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
@classmethod
|
||||
def check_can_migrate_out(cls, user, to_user_id):
|
||||
"""Raises an exception if a user can't yet migrate to a native account.
|
||||
|
||||
For example, if ``to_user_id`` isn't on this protocol, or if ``user`` is on
|
||||
this protocol, or isn't bridged to this protocol.
|
||||
|
||||
If the user is ready to migrate, returns ``None``.
|
||||
|
||||
Subclasses may override this to add more criteria, but they should call this
|
||||
implementation first.
|
||||
|
||||
Args:
|
||||
user (models.User)
|
||||
to_user_id (str)
|
||||
|
||||
Raises:
|
||||
ValueError: if ``user`` isn't ready to migrate to this protocol yet
|
||||
"""
|
||||
def _error(msg):
|
||||
logger.warning(msg)
|
||||
raise ValueError(msg)
|
||||
|
||||
if cls.owns_id(to_user_id) is False:
|
||||
_error(f"{to_user_id} doesn't look like an {cls.LABEL} id")
|
||||
elif isinstance(user, cls):
|
||||
_error(f"{user.handle_or_id()} is on {cls.PHRASE}")
|
||||
elif not user.is_enabled(cls):
|
||||
_error(f"{user.handle_or_id()} isn't currently bridged to {cls.PHRASE}")
|
||||
|
||||
@classmethod
|
||||
def migrate_in(cls, user, from_user_id, **kwargs):
|
||||
"""Migrates a native account in to be a bridged account.
|
||||
|
|
|
|||
|
|
@ -2344,6 +2344,30 @@ class ActivityPubTest(TestCase):
|
|||
with self.assertRaises(ValueError):
|
||||
ActivityPub.migrate_out(self.user, 'http://in.st/to')
|
||||
|
||||
def test_check_can_migrate_out(self, _, mock_get, mock_post):
|
||||
mock_get.return_value = self.as2_resp({
|
||||
**ACTOR,
|
||||
'alsoKnownAs': ['http://localhost/user.com'],
|
||||
})
|
||||
|
||||
# shouldn't raise
|
||||
ActivityPub.check_can_migrate_out(self.user, 'http://in.st/to')
|
||||
|
||||
def test_check_can_migrate_out_no_alias_in_to_actor(self, _, mock_get, __):
|
||||
mock_get.return_value = self.as2_resp(ACTOR)
|
||||
|
||||
self.user.enabled_protocols = ['activitypub']
|
||||
with self.assertRaises(ValueError):
|
||||
ActivityPub.check_can_migrate_out(self.user, 'http://in.st/to')
|
||||
|
||||
mock_get.return_value = self.as2_resp({
|
||||
**ACTOR,
|
||||
'alsoKnownAs': ['oth', 'er'],
|
||||
})
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
ActivityPub.check_can_migrate_out(self.user, 'http://in.st/to')
|
||||
|
||||
|
||||
class ActivityPubUtilsTest(TestCase):
|
||||
def setUp(self):
|
||||
|
|
|
|||
|
|
@ -1024,6 +1024,24 @@ class ProtocolTest(TestCase):
|
|||
Fake.bot_follow(user)
|
||||
self.assertEqual([], Fake.sent)
|
||||
|
||||
def test_check_can_migrate_out(self, *_):
|
||||
fake = Fake(id='fake:user', enabled_protocols=['other'])
|
||||
OtherFake.check_can_migrate_out(fake, 'other:user')
|
||||
|
||||
def test_check_can_migrate_out_bad_user_id(self, *_):
|
||||
fake = Fake(id='fake:user', enabled_protocols=['other'])
|
||||
with self.assertRaises(ValueError):
|
||||
OtherFake.check_can_migrate_out(self.user, 'at://did:xyz')
|
||||
|
||||
def test_check_can_migrate_out_user_not_enabled(self, *_):
|
||||
fake = Fake(id='fake:user', enabled_protocols=['efake'])
|
||||
with self.assertRaises(ValueError):
|
||||
OtherFake.check_can_migrate_out(fake, 'https://in.st/eve')
|
||||
|
||||
def test_check_can_migrate_out_same_protocol(self, *_):
|
||||
fake = Fake(id='fake:user', enabled_protocols=['other'])
|
||||
with self.assertRaises(ValueError):
|
||||
Fake.check_can_migrate_out(fake, 'fake:eve')
|
||||
|
||||
class ProtocolReceiveTest(TestCase):
|
||||
|
||||
|
|
|
|||
Ładowanie…
Reference in New Issue