コード例 #1
0
def send_profile(profile_id, recipients=None):
    """Handle sending a Profile object out via the federation layer.

    :param profile_id: Profile.id of profile to send
    :param recipients: Optional list of recipients, see `federation.outbound.handle_send` parameters
    """
    try:
        profile = Profile.objects.get(id=profile_id, user__isnull=False)
    except Profile.DoesNotExist:
        logger.warning("send_profile - No local profile found with id %s",
                       profile_id)
        return
    entity = make_federable_profile(profile)
    if not entity:
        logger.warning("send_profile - No entity for %s", profile)
        return
    if settings.DEBUG:
        # Don't send in development mode
        return
    if not recipients:
        # If we have Matrix support enabled, also add the appservice
        if settings.SOCIALHOME_MATRIX_ENABLED:
            recipients = [profile.get_recipient_for_matrix_appservice()]
        else:
            recipients = []
        recipients.extend(_get_remote_followers(profile, profile.visibility))

    logger.debug("send_profile - sending to recipients: %s", recipients)
    handle_send(entity,
                profile.federable,
                recipients,
                payload_logger=get_outbound_payload_logger())
コード例 #2
0
def send_profile_retraction(profile):
    """Handle sending of retractions for profiles.

    Only sent for public and limited profiles. Reason: we might actually leak user information
    outside for profiles which were never federated outside if we send for example
    SELF or SITE profile retractions.

    This must be called as a pre_delete signal or it will fail.
    """
    if profile.visibility not in (Visibility.PUBLIC,
                                  Visibility.LIMITED) or not profile.is_local:
        return
    entity = make_federable_retraction(profile)
    if entity:
        if settings.DEBUG:
            # Don't send in development mode
            return
        recipients = _get_remote_followers(profile, profile.visibility)
        logger.debug("send_profile_retraction - sending to recipients: %s",
                     recipients)
        handle_send(entity,
                    profile.federable,
                    recipients,
                    payload_logger=get_outbound_payload_logger())
    else:
        logger.warning("send_profile_retraction - No retraction entity for %s",
                       profile)
コード例 #3
0
def send_share(content_id, activity_fid):
    """Handle sending a share of a Content object to the federation layer.

    Currently we only deliver public shares.
    """
    try:
        content = Content.objects.get(id=content_id,
                                      visibility=Visibility.PUBLIC,
                                      content_type=ContentType.SHARE,
                                      local=True)
    except Content.DoesNotExist:
        logger.warning("No local share found with id %s", content_id)
        return
    entity = make_federable_content(content)
    if entity:
        entity.activity_id = activity_fid
        if settings.DEBUG:
            # Don't send in development mode
            return
        recipients = _get_remote_followers(content.author, content.visibility)
        if not content.share_of.local:
            # Send to original author
            recipients.append(
                content.share_of.author.get_recipient_for_visibility(
                    content.visibility))
        logger.debug("send_share - sending to recipients: %s", recipients)
        handle_send(entity,
                    content.author.federable,
                    recipients,
                    payload_logger=get_outbound_payload_logger())
    else:
        logger.warning("send_share - No entity for %s", content)
コード例 #4
0
ファイル: tasks.py プロジェクト: ra2003/socialhome
def send_profile(profile_id, recipients=None):
    """Handle sending a Profile object out via the federation layer.

    :param profile_id: Profile.id of profile to send
    :param recipients: Optional list of recipients, see `federation.outbound.handle_send` parameters
    """
    try:
        profile = Profile.objects.get(id=profile_id, user__isnull=False)
    except Profile.DoesNotExist:
        logger.warning("send_profile - No local profile found with id %s",
                       profile_id)
        return
    entity = make_federable_profile(profile)
    if not entity:
        logger.warning("send_profile - No entity for %s", profile)
        return
    if settings.DEBUG:
        # Don't send in development mode
        return
    if not recipients:
        recipients = _get_remote_followers(profile, profile.visibility)
    logger.debug("send_profile - sending to recipients: %s", recipients)
    handle_send(entity,
                profile.federable,
                recipients,
                payload_logger=get_outbound_payload_logger())
コード例 #5
0
def send_content(content_id, activity_fid, recipient_id=None):
    """
    Handle sending a Content object out via the federation layer.
    """
    try:
        content = Content.objects.get(
            id=content_id,
            visibility__in=(Visibility.PUBLIC, Visibility.LIMITED),
            content_type=ContentType.CONTENT,
            local=True,
        )
    except Content.DoesNotExist:
        logger.warning("No local content found with id %s", content_id)
        return
    if recipient_id:
        try:
            recipient = Profile.objects.get(id=recipient_id, user__isnull=True)
        except Profile.DoesNotExist:
            logger.warning("No remote recipient found with id %s",
                           recipient_id)
            return
    else:
        recipient = None
    entity = make_federable_content(content)
    if entity:
        entity.activity_id = activity_fid
        if settings.DEBUG:
            # Don't send in development mode
            return
        recipients = []
        if recipient:
            recipients.append(
                recipient.get_recipient_for_visibility(content.visibility))
        else:
            if content.visibility == Visibility.PUBLIC:
                # If we have Matrix support enabled, also add the appservice
                if settings.SOCIALHOME_MATRIX_ENABLED:
                    recipients.append(
                        content.author.get_recipient_for_matrix_appservice())
                if settings.SOCIALHOME_RELAY_ID:
                    recipients.append({
                        "endpoint": settings.SOCIALHOME_RELAY_ID,
                        "fid": "",
                        "public": True,
                        "protocol": "diaspora"
                    })
            recipients.extend(
                _get_remote_followers(content.author, content.visibility))

        logger.debug("send_content - sending to recipients: %s", recipients)
        handle_send(entity,
                    content.author.federable,
                    recipients,
                    payload_logger=get_outbound_payload_logger())
    else:
        logger.warning("send_content - No entity for %s", content)
コード例 #6
0
def send_reply(content_id, activity_fid):
    """
    Handle sending a Content object that is a reply out via the federation layer.
    """
    try:
        content = Content.objects.get(
            id=content_id,
            visibility__in=(Visibility.PUBLIC, Visibility.LIMITED),
            content_type=ContentType.REPLY,
            local=True,
        )
    except Content.DoesNotExist:
        logger.warning("No content found with id %s", content_id)
        return
    entity = make_federable_content(content)
    if not entity:
        logger.warning("send_reply - No entity for %s", content)
    entity.activity_id = activity_fid
    if settings.DEBUG:
        # Don't send in development mode
        return
    recipients = []
    if not content.root_parent.author.is_local:
        recipients.append(
            content.root_parent.author.get_recipient_for_visibility(
                content.visibility))
    if content.visibility == Visibility.PUBLIC:
        recipients.extend(
            _get_remote_participants_for_content(content,
                                                 exclude=content.author.fid,
                                                 include_remote=True), )
        recipients.extend(
            _get_remote_followers(
                content.author,
                content.visibility,
                exclude=content.author.fid,
            ))
    elif content.visibility == Visibility.LIMITED:
        recipients.extend(_get_limited_recipients(content.author.fid, content))
    else:
        return
    if not recipients:
        logger.debug("send_reply - no remote recipients for content: %s",
                     content.id)
        return
    logger.debug("send_reply - sending to recipients: %s", recipients)
    handle_send(entity,
                content.author.federable,
                recipients,
                payload_logger=get_outbound_payload_logger())
コード例 #7
0
def forward_entity(entity, target_content_id):
    """Handle forwarding of an entity related to a target content.

    For example: remote replies on local content, remote shares on local content.
    """
    try:
        target_content = Content.objects.get(
            id=target_content_id,
            visibility__in=(Visibility.PUBLIC, Visibility.LIMITED),
            local=True,
        )
    except Content.DoesNotExist:
        logger.warning("forward_entity - No local content found with id %s",
                       target_content_id)
        return
    try:
        content = Content.objects.fed(
            entity.id,
            visibility__in=(Visibility.PUBLIC, Visibility.LIMITED)).get()
    except Content.DoesNotExist:
        logger.warning("forward_entity - No content found with uuid %s",
                       entity.id)
        return
    if settings.DEBUG:
        # Don't send in development mode
        return
    if target_content.visibility == Visibility.PUBLIC:
        recipients = _get_remote_participants_for_content(
            target_content, exclude=entity.actor_id)
        recipients.extend(
            _get_remote_followers(
                target_content.author,
                target_content.visibility,
                exclude=entity.actor_id,
            ))
    elif target_content.visibility == Visibility.LIMITED and content.content_type == ContentType.REPLY:
        recipients = _get_limited_recipients(entity.actor_id, target_content)
    else:
        return
    logger.debug("forward_entity - sending to recipients: %s", recipients)
    handle_send(
        entity,
        content.author.federable,
        recipients,
        parent_user=target_content.author.federable,
        payload_logger=get_outbound_payload_logger(),
    )
コード例 #8
0
def send_content_retraction(content, author_id):
    """
    Handle sending of retractions for content.
    """
    if content.visibility not in (Visibility.PUBLIC,
                                  Visibility.LIMITED) or not content.local:
        return
    author = Profile.objects.get(id=author_id)
    entity = make_federable_retraction(content, author)
    if entity:
        if settings.DEBUG:
            # Don't send in development mode
            return
        if content.visibility == Visibility.PUBLIC:
            recipients = []
            if settings.SOCIALHOME_RELAY_ID:
                recipients.append({
                    "endpoint": settings.SOCIALHOME_RELAY_ID,
                    "fid": "",
                    "public": True,
                    "protocol": "diaspora"
                })
            recipients.extend(_get_remote_followers(author,
                                                    content.visibility))
        else:
            recipients = _get_limited_recipients(author.fid, content)

        logger.debug("send_content_retraction - sending to recipients: %s",
                     recipients)
        # Queue to the background since sending could take a while
        django_rq.enqueue(
            handle_send,
            entity,
            author.federable,
            recipients,
            payload_logger=get_outbound_payload_logger(),
            job_timeout=10000,
        )
    else:
        logger.warning("send_content_retraction - No retraction entity for %s",
                       content)
コード例 #9
0
def send_follow_change(profile_id, followed_id, follow):
    """Handle sending of a local follow of a remote profile."""
    try:
        profile = Profile.objects.get(id=profile_id, user__isnull=False)
    except Profile.DoesNotExist:
        logger.warning(
            "send_follow_change - No local profile %s found to send follow with",
            profile_id)
        return
    try:
        remote_profile = Profile.objects.get(id=followed_id, user__isnull=True)
    except Profile.DoesNotExist:
        logger.warning(
            "send_follow_change - No remote profile %s found to send follow for",
            followed_id)
        return
    if settings.DEBUG:
        # Don't send in development mode
        return
    entity = base.Follow(
        activity_id=f'{profile.fid}#follow-{uuid4()}',
        actor_id=profile.fid,
        target_id=remote_profile.fid,
        following=follow,
        handle=profile.handle,
        target_handle=remote_profile.handle,
    )
    # Explicitly use limited visibility to force private endpoint
    recipients = [
        remote_profile.get_recipient_for_visibility(Visibility.LIMITED)
    ]
    logger.debug("send_follow_change - sending to recipients: %s", recipients)
    handle_send(entity,
                profile.federable,
                recipients,
                payload_logger=get_outbound_payload_logger())
    # Also trigger a profile send
    send_profile(profile_id, recipients=recipients)