From f17f9df27ef3b890a152831f20043625de5a6111 Mon Sep 17 00:00:00 2001 From: Michael Manfre Date: Wed, 28 Dec 2022 12:52:39 -0500 Subject: [PATCH] Identity.by_username_and_domain has more awareness of Domain (#303) --- activities/services/search.py | 2 +- users/models/identity.py | 33 +++++++++++++++++++++++++++++---- users/shortcuts.py | 2 +- 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/activities/services/search.py b/activities/services/search.py index 621474f..a2b2d94 100644 --- a/activities/services/search.py +++ b/activities/services/search.py @@ -44,7 +44,7 @@ class SearchService: if self.identity is not None: # Allow authenticated users to fetch remote identity = Identity.by_username_and_domain( - username, domain, fetch=True + username, domain_instance or domain, fetch=True ) if identity and identity.state == IdentityStates.outdated: async_to_sync(identity.fetch_actor)() diff --git a/users/models/identity.py b/users/models/identity.py index ca948be..545872a 100644 --- a/users/models/identity.py +++ b/users/models/identity.py @@ -303,10 +303,34 @@ class Identity(StatorModel): ### Alternate constructors/fetchers ### @classmethod - def by_username_and_domain(cls, username, domain, fetch=False, local=False): + def by_username_and_domain( + cls, + username: str, + domain: str | Domain, + fetch: bool = False, + local: bool = False, + ): + """ + Get an Identity by username and domain. + + When fetch is True, a failed lookup will do a webfinger lookup to attempt to do + a lookup by actor_uri, creating an Identity record if one does not exist. When + local is True, lookups will be restricted to local domains. + + If domain is a Domain, domain.local is used instead of passsed local. + + """ if username.startswith("@"): raise ValueError("Username must not start with @") - domain = domain.lower() + + domain_instance = None + + if isinstance(domain, Domain): + domain_instance = domain + local = domain.local + domain = domain.domain + else: + domain = domain.lower() try: if local: return cls.objects.get( @@ -333,11 +357,12 @@ class Identity(StatorModel): pass # OK, make one username, domain = handle.split("@") - domain = Domain.get_remote_domain(domain) + if not domain_instance: + domain_instance = Domain.get_remote_domain(domain) return cls.objects.create( actor_uri=actor_uri, username=username, - domain_id=domain, + domain_id=domain_instance, local=False, ) return None diff --git a/users/shortcuts.py b/users/shortcuts.py index 9aadb66..6ae7c21 100644 --- a/users/shortcuts.py +++ b/users/shortcuts.py @@ -25,7 +25,7 @@ def by_handle_or_404(request, handle, local=True, fetch=False) -> Identity: domain = domain_instance.domain identity = Identity.by_username_and_domain( username, - domain, + domain_instance, local=local, fetch=fetch, )