def test_from_remote_profile_absolute_image_url(self): remote_profile = BaseProfileFactory(public=False) remote_profile.image_urls["small"] = "https://example1.com/sm" remote_profile.image_urls["medium"] = "https://example2.com/me" remote_profile.image_urls["large"] = "https://example3.com/lg" profile = Profile.from_remote_profile(remote_profile) self.assertEqual(profile.image_url_small, "https://example1.com/sm") self.assertEqual(profile.image_url_medium, "https://example2.com/me") self.assertEqual(profile.image_url_large, "https://example3.com/lg")
def test_from_remote_profile_relative_image_url(self): remote_profile = BaseProfileFactory(public=False) remote_profile.handle = "*****@*****.**" remote_profile.image_urls["small"] = "/sm" remote_profile.image_urls["medium"] = "/me" remote_profile.image_urls["large"] = "/lg" profile = Profile.from_remote_profile(remote_profile) self.assertEqual(profile.image_url_small, "https://example.com/sm") self.assertEqual(profile.image_url_medium, "https://example.com/me") self.assertEqual(profile.image_url_large, "https://example.com/lg")
def test_from_remote_profile(self): remote_profile = BaseProfileFactory(public=False) profile = Profile.from_remote_profile(remote_profile) self.assertEqual(profile.guid, remote_profile.guid) self.assertEqual(profile.handle, remote_profile.handle) self.assertEqual(profile.name, remote_profile.name) self.assertEqual(profile.visibility, Visibility.LIMITED) self.assertEqual(profile.image_url_large, remote_profile.image_urls["large"]) self.assertEqual(profile.image_url_medium, remote_profile.image_urls["medium"]) self.assertEqual(profile.image_url_small, remote_profile.image_urls["small"]) self.assertEqual(profile.location, remote_profile.location) self.assertEqual(profile.email, remote_profile.email) self.assertEqual(profile.rsa_public_key, remote_profile.public_key) # Update to public remote_profile_update = BaseProfileFactory( public=True, guid=remote_profile.guid, handle=remote_profile.handle) profile = Profile.from_remote_profile(remote_profile_update) self.assertEqual(profile.guid, remote_profile.guid) self.assertEqual(profile.handle, remote_profile.handle) self.assertEqual(profile.visibility, Visibility.PUBLIC) # Make sure public key doesn't get deleted if it doesn't have a value public_key = profile.rsa_public_key assert public_key remote_profile_update = BaseProfileFactory( public_key="", guid=remote_profile.guid, handle=remote_profile.handle) profile = Profile.from_remote_profile(remote_profile_update) self.assertEqual(profile.rsa_public_key, public_key) remote_profile_update = BaseProfileFactory( public_key=None, guid=remote_profile.guid, handle=remote_profile.handle) profile = Profile.from_remote_profile(remote_profile_update) self.assertEqual(profile.rsa_public_key, public_key)
def test_from_remote_profile(self): remote_profile = BaseProfileFactory(public=False) profile = Profile.from_remote_profile(remote_profile) self.assertEqual(profile.fid, remote_profile.id) self.assertEqual(profile.name, remote_profile.name) self.assertEqual(profile.visibility, Visibility.PUBLIC) self.assertEqual(profile.image_url_large, remote_profile.image_urls["large"]) self.assertEqual(profile.image_url_medium, remote_profile.image_urls["medium"]) self.assertEqual(profile.image_url_small, remote_profile.image_urls["small"]) self.assertEqual(profile.location, remote_profile.location) self.assertEqual(profile.email, remote_profile.email) self.assertEqual(profile.rsa_public_key, remote_profile.public_key) # Make sure public key doesn't get deleted if it doesn't have a value public_key = profile.rsa_public_key assert public_key remote_profile_update = BaseProfileFactory(public_key="", id=remote_profile.id) profile = Profile.from_remote_profile(remote_profile_update) self.assertEqual(profile.rsa_public_key, public_key) remote_profile_update = BaseProfileFactory(public_key=None, id=remote_profile.id) profile = Profile.from_remote_profile(remote_profile_update) self.assertEqual(profile.rsa_public_key, public_key)
def process_entities(entities, receiving_profile=None): """Process a list of entities.""" for entity in entities: logger.info("Entity: %s", entity) sender_id = entity.id if isinstance(entity, base.Profile) else entity.actor_id profile = get_sender_profile(sender_id) if not profile: logger.warning("No sender profile for entity %s, skipping", entity) continue try: if isinstance(entity, base.Post): process_entity_post(entity, profile, receiving_profile=receiving_profile) elif isinstance(entity, base.Retraction): process_entity_retraction(entity, profile) elif isinstance(entity, base.Comment): process_entity_comment(entity, profile, receiving_profile=receiving_profile) elif isinstance(entity, base.Follow): process_entity_follow(entity, profile) elif isinstance(entity, base.Profile): Profile.from_remote_profile(entity) elif isinstance(entity, base.Share): process_entity_share(entity, profile) except Exception as ex: logger.exception("Failed to handle %s: %s", entity.id, ex)
def sender_key_fetcher(handle): """Return the RSA public key for a handle, if found. Fetches the key first from a local Profile and if not found, looks for a remote Profile over the network. :param handle: Handle of profile :type handle: str :returns: RSA public key or None :rtype: str """ try: profile = Profile.objects.get(handle=handle, user__isnull=True) except Profile.DoesNotExist: remote_profile = retrieve_remote_profile(handle) if not remote_profile: logger.warning( "Remote profile %s for sender key not found locally or remotely.", handle) return None # We might as well create the profile locally here since we'll need it again soon Profile.from_remote_profile(remote_profile) return remote_profile.public_key else: return profile.rsa_public_key
def get_sender_profile(sender): """Get or create sender profile. Fetch it from federation layer if necessary. """ try: sender_profile = Profile.objects.get(handle=sender) except Profile.DoesNotExist: remote_profile = retrieve_remote_profile(sender) if not remote_profile: logger.warning("Remote profile %s not found locally or remotely.", sender) return sender_profile = Profile.from_remote_profile(remote_profile) return sender_profile
def get_sender_profile(sender): """Get or create sender profile. Fetch it from federation layer if necessary or if the public key is empty for some reason. """ try: sender_profile = Profile.objects.exclude(rsa_public_key="").get( handle=sender) except Profile.DoesNotExist: remote_profile = retrieve_remote_profile(sender) if not remote_profile: logger.warning("Remote profile %s not found locally or remotely.", sender) return sender_profile = Profile.from_remote_profile(remote_profile) return sender_profile
def get(self, request, *args, **kwargs): """See if we have a direct match. If so redirect, if not, search. Try fetching a remote profile if the search term is a handle or fid. """ q = safe_text(request.GET.get("q")) if q: q = q.strip().lower() self.q = q # Check if direct tag matches if q.startswith('#'): try: tag = Tag.objects.filter(name=q[1:]).annotate( content_count=Count('contents')).filter( content_count__gt=0).get() except Tag.DoesNotExist: pass else: return redirect(tag.get_absolute_url()) # Check if profile matches profile = None try: profile = Profile.objects.visible_for_user( request.user).fed(q).get() except Profile.DoesNotExist: # Try a remote search # TODO currently only if diaspora handle if validate_handle(q): try: remote_profile = retrieve_remote_profile(q) except (AttributeError, ValueError, xml.parsers.expat.ExpatError): # Catch various errors parsing the remote profile return super().get(request, *args, **kwargs) if remote_profile: profile = Profile.from_remote_profile(remote_profile) if profile: return redirect( reverse("users:profile-detail", kwargs={"uuid": profile.uuid})) try: return super().get(request, *args, **kwargs) except QueryError: # Re-render the form messages.warning( self.request, _("Search string is invalid, please try another one.")) return HttpResponseRedirect(self.get_success_url())
def get(self, request, *args, **kwargs): """See if we have a direct match. If so redirect, if not, search. Try fetching a remote profile if the search term is a handle or fid. """ q = safe_text(request.GET.get("q")) if q: q = q.strip().lower() self.q = q # Check if direct tag matches if q.startswith('#'): try: tag = Tag.objects.filter( name=q[1:] ).annotate( content_count=Count('contents') ).filter( content_count__gt=0 ).get() except Tag.DoesNotExist: pass else: return redirect(tag.get_absolute_url()) # Check if profile matches profile = None try: profile = Profile.objects.visible_for_user(request.user).fed(q).get() except Profile.DoesNotExist: # Try a remote search # TODO currently only if diaspora handle if validate_handle(q): try: remote_profile = retrieve_remote_profile(q) except (AttributeError, ValueError, xml.parsers.expat.ExpatError): # Catch various errors parsing the remote profile return super().get(request, *args, **kwargs) if remote_profile: profile = Profile.from_remote_profile(remote_profile) if profile: return redirect(reverse("users:profile-detail", kwargs={"uuid": profile.uuid})) try: return super().get(request, *args, **kwargs) except QueryError: # Re-render the form messages.warning(self.request, _("Search string is invalid, please try another one.")) return HttpResponseRedirect(self.get_success_url())
def get_sender_profile(sender: str) -> Optional[Profile]: """Get or create sender profile. Fetch it from federation layer if necessary or if the public key is empty for some reason. """ try: logger.debug("get_sender_profile - looking from local db using %s", sender) sender_profile = Profile.objects.fed(sender).exclude(rsa_public_key="").get() except Profile.DoesNotExist: logger.debug("get_sender_profile - %s was not found, fetching from remote", sender) remote_profile = retrieve_remote_profile(sender) if not remote_profile: logger.warning("get_sender_profile - Remote profile %s not found locally or remotely.", sender) return sender_profile = Profile.from_remote_profile(remote_profile) else: if sender_profile.is_local: logger.warning("get_sender_profile - %s is local! Skip.", sender) return return sender_profile
def get(self, request, *args, **kwargs): """See if we have a direct match. If so redirect, if not, search. Try fetching a remote profile if the search term is a handle. """ try: q = safe_text(request.GET.get("q")) if q: q = q.strip().lower() validate_email(q) except ValidationError: pass else: profile = None try: profile = Profile.objects.visible_for_user( request.user).get(handle=q) except Profile.DoesNotExist: # Try a remote search try: remote_profile = retrieve_remote_profile(q) except (AttributeError, ValueError, xml.parsers.expat.ExpatError): # Catch various errors parsing the remote profile return super().get(request, *args, **kwargs) if remote_profile: profile = Profile.from_remote_profile(remote_profile) if profile: return redirect( reverse("users:profile-detail", kwargs={"guid": profile.guid})) try: return super().get(request, *args, **kwargs) except QueryError: # Re-render the form messages.warning( self.request, _("Search string is invalid, please try another one.")) return HttpResponseRedirect(self.get_success_url())
def get(self, request, *args, **kwargs): """See if we have a direct match. If so redirect, if not, search. Try fetching a remote profile if the search term is a handle. """ try: q = safe_text(request.GET.get("q")) if q: q = q.strip() validate_email(q) except ValidationError: pass else: profile = None try: profile = Profile.objects.visible_for_user(request.user).get(handle=q) except Profile.DoesNotExist: # Try a remote search remote_profile = retrieve_remote_profile(q) if remote_profile: profile = Profile.from_remote_profile(remote_profile) if profile: return redirect(reverse("users:profile-detail", kwargs={"guid": profile.guid})) return super().get(request, *args, **kwargs)