diff --git a/ids.py b/ids.py index c390077..044045e 100644 --- a/ids.py +++ b/ids.py @@ -149,6 +149,34 @@ def translate_user_id(*, id, from_, to): assert False, (id, from_.LABEL, to.LABEL) +def normalize_user_id(*, id, proto): + """Normalizes a user id to its canonical representation in a given protocol. + + Examples: + + * Web: + * user.com => user.com + * www.user.com => user.com + * https://user.com/ => user.com + * ATProto: + * did:plc:123 => did:plc:123 + * https://bsky.app/profile/did:plc:123 => did:plc:123 + + Args: + id (str) + proto (protocol.Protocol) + + Returns: + str: the normalized user id + """ + normalized = translate_user_id(id=id, from_=proto, to=proto) + + if proto.LABEL == 'web': + normalized = util.domain_from_link(normalized) + + return normalized + + def translate_handle(*, handle, from_, to, enhanced): """Translates a user handle from one protocol to another. diff --git a/tests/test_ids.py b/tests/test_ids.py index 0f37399..2b01917 100644 --- a/tests/test_ids.py +++ b/tests/test_ids.py @@ -4,6 +4,7 @@ from unittest.mock import patch from activitypub import ActivityPub from atproto import ATProto from flask_app import app +import ids from ids import translate_handle, translate_object_id, translate_user_id from models import Target from .testutil import Fake, TestCase @@ -72,7 +73,7 @@ class IdsTest(TestCase): (Web, 'fed.brid.gy', ActivityPub, 'https://fed.brid.gy/fed.brid.gy'), (Web, 'bsky.brid.gy', ActivityPub, 'https://bsky.brid.gy/bsky.brid.gy'), ]: - with self.subTest(from_=from_.LABEL, to=to.LABEL): + with self.subTest(id=id, from_=from_.LABEL, to=to.LABEL): self.assertEqual(expected, translate_user_id( id=id, from_=from_, to=to)) @@ -82,7 +83,7 @@ class IdsTest(TestCase): (ActivityPub, 'https://instance/user'), (Fake, 'fake:user'), ]: - with self.subTest(proto=proto.LABEL): + with self.subTest(proto=proto.LABEL, id=id): self.assertIsNone(translate_user_id(id=id, from_=proto, to=ATProto)) def test_translate_user_id_use_instead(self): @@ -114,6 +115,20 @@ class IdsTest(TestCase): self.assertEqual('https://bsky.brid.gy/on-bsky.com', translate_user_id( id='on-bsky.com', from_=Web, to=ActivityPub)) + def test_normalize_user_id(self): + for proto, id, expected in [ + (ActivityPub, 'https://inst/user', 'https://inst/user'), + (ATProto, 'did:plc:456', 'did:plc:456'), + (ATProto, 'https://bsky.app/profile/did:plc:123', 'did:plc:123'), + (Fake, 'fake:user', 'fake:user'), + (Web, 'user.com', 'user.com'), + (Web, 'https://user.com/', 'user.com'), + (Web, 'https://www.user.com/', 'user.com'), + (Web, 'm.user.com', 'user.com'), + ]: + with self.subTest(id=id, proto=proto): + self.assertEqual(expected, ids.normalize_user_id(id=id, proto=proto)) + def test_translate_handle(self): for from_, handle, to, expected in [ # basic