From 3d4ea6637cabcdc392039f997aa9a968a7e4451e Mon Sep 17 00:00:00 2001 From: freamon Date: Sun, 24 Nov 2024 21:45:39 +0000 Subject: [PATCH] apf part 33: Log unmatched activity, and delete old code --- app/activitypub/routes.py | 802 +------------------------------------- 1 file changed, 1 insertion(+), 801 deletions(-) diff --git a/app/activitypub/routes.py b/app/activitypub/routes.py index dc2add51..5b5e0c5f 100644 --- a/app/activitypub/routes.py +++ b/app/activitypub/routes.py @@ -1103,807 +1103,7 @@ def process_inbox_request(request_json, store_ap_json): return - - # -- below this point is code that will be incrementally replaced to use log_incoming_ap() instead -- - - # save all incoming data to aid in debugging and development. Set result to 'success' if things go well - activity_log = ActivityPubLog(direction='in', result='failure') - - if 'id' in request_json: - activity_log.activity_id = request_json['id'] - if site.log_activitypub_json: - activity_log.activity_json = json.dumps(request_json) - activity_log.result = 'processing' - db.session.add(activity_log) - db.session.commit() - - if 'type' in request_json: - activity_log.activity_type = request_json['type'] - if not instance_blocked(request_json['id']): - # Create is new content. Update is often an edit, but Updates from Lemmy can also be new content - if request_json['type'] == 'Create' or request_json['type'] == 'Update': - activity_log.activity_type = 'Create' - user_ap_id = request_json['object']['attributedTo'] if 'attributedTo' in request_json['object'] and isinstance(request_json['object']['attributedTo'], str) else None - if user_ap_id is None: # if there is no attributedTo, fall back to the actor on the parent object - user_ap_id = request_json['actor'] if 'actor' in request_json and isinstance(request_json['actor'], str) else None - if request_json['object']['type'] == 'ChatMessage': - activity_log.activity_type = 'Create ChatMessage' - sender = find_actor_or_create(user_ap_id) - recipient_ap_id = request_json['object']['to'][0] - recipient = find_actor_or_create(recipient_ap_id) - if sender and recipient and recipient.is_local(): - if sender.created_recently() or sender.reputation <= -10: - activity_log.exception_message = "Sender not eligible to send" - elif recipient.has_blocked_user(sender.id) or recipient.has_blocked_instance(sender.instance_id): - activity_log.exception_message = "Sender blocked by recipient" - else: - # Find existing conversation to add to - existing_conversation = Conversation.find_existing_conversation(recipient=recipient, sender=sender) - if not existing_conversation: - existing_conversation = Conversation(user_id=sender.id) - existing_conversation.members.append(recipient) - existing_conversation.members.append(sender) - db.session.add(existing_conversation) - db.session.commit() - # Save ChatMessage to DB - encrypted = request_json['object']['encrypted'] if 'encrypted' in request_json['object'] else None - new_message = ChatMessage(sender_id=sender.id, recipient_id=recipient.id, conversation_id=existing_conversation.id, - body=request_json['object']['source']['content'], - body_html=markdown_to_html(request_json['object']['source']['content']), - encrypted=encrypted) - db.session.add(new_message) - existing_conversation.updated_at = utcnow() - db.session.commit() - - # Notify recipient - notify = Notification(title=shorten_string('New message from ' + sender.display_name()), - url=f'/chat/{existing_conversation.id}#message_{new_message}', user_id=recipient.id, - author_id=sender.id) - db.session.add(notify) - recipient.unread_notifications += 1 - existing_conversation.read = False - db.session.commit() - activity_log.result = 'success' - else: - try: - community_ap_id = '' - locations = ['audience', 'cc', 'to'] - if 'object' in request_json: - rjs = [request_json, request_json['object']] - else: - rjs = [request_json] - followers_suffix = '/followers' - for rj in rjs: - for location in locations: - if location in rj: - potential_id = rj[location] - if isinstance(potential_id, str): - if not potential_id.startswith('https://www.w3.org') and not potential_id.endswith(followers_suffix): - community_ap_id = potential_id - if isinstance(potential_id, list): - for c in potential_id: - if not c.startswith('https://www.w3.org') and not c.endswith(followers_suffix): - community_ap_id = c - break - if community_ap_id: - break - if community_ap_id: - break - if not community_ap_id and 'object' in request_json and \ - 'inReplyTo' in request_json['object'] and request_json['object']['inReplyTo'] is not None: - post_being_replied_to = Post.query.filter_by(ap_id=request_json['object']['inReplyTo']).first() - if post_being_replied_to: - community_ap_id = post_being_replied_to.community.ap_profile_id - else: - comment_being_replied_to = PostReply.query.filter_by(ap_id=request_json['object']['inReplyTo']).first() - if comment_being_replied_to: - community_ap_id = comment_being_replied_to.community.ap_profile_id - if not community_ap_id and 'object' in request_json and request_json['object']['type'] == 'Video': # PeerTube - if 'attributedTo' in request_json['object'] and isinstance(request_json['object']['attributedTo'], list): - for a in request_json['object']['attributedTo']: - if a['type'] == 'Group': - community_ap_id = a['id'] - if a['type'] == 'Person': - user_ap_id = a['id'] - if not community_ap_id: - activity_log.result = 'failure' - activity_log.exception_message = 'Unable to extract community' - db.session.commit() - return - except: - activity_log.activity_type = 'exception' - db.session.commit() - return - if 'object' in request_json: - if not ensure_domains_match(request_json['object']): - activity_log.result = 'failure' - activity_log.exception_message = 'Domains do not match' - db.session.commit() - return - community = find_actor_or_create(community_ap_id, community_only=True) - if community and community.local_only: - activity_log.exception_message = 'Remote Create in local_only community' - activity_log.result = 'ignored' - db.session.commit() - return - user = find_actor_or_create(user_ap_id) - if user and not user.is_local(): - if community: - user.last_seen = community.last_active = site.last_active = utcnow() - else: - user.last_seen = site.last_active = utcnow() - object_type = request_json['object']['type'] - new_content_types = ['Page', 'Article', 'Link', 'Note', 'Question'] - if object_type in new_content_types: # create or update a post - in_reply_to = request_json['object']['inReplyTo'] if 'inReplyTo' in request_json['object'] else None - if not in_reply_to: # Creating a new post - post = Post.query.filter_by(ap_id=request_json['object']['id']).first() - if post: - if request_json['type'] == 'Create': - activity_log.result = 'ignored' - activity_log.exception_message = 'Create received for already known object' - db.session.commit() - return - else: - activity_log.activity_type = 'Update' - if can_edit(request_json['actor'], post): - update_post_from_activity(post, request_json) - announce_activity_to_followers(post.community, post.author, request_json) - activity_log.result = 'success' - else: - activity_log.exception_message = 'Edit attempt denied' - else: - if can_create_post(user, community): - try: - post = create_post(activity_log, community, request_json, user) - if post: - announce_activity_to_followers(community, user, request_json) - activity_log.result = 'success' - except TypeError as e: - activity_log.exception_message = 'TypeError. See log file.' - current_app.logger.error('TypeError: ' + str(request_json)) - post = None - else: - post = None - else: # Creating a reply / comment - reply = PostReply.query.filter_by(ap_id=request_json['object']['id']).first() - if reply: - if request_json['type'] == 'Create': - activity_log.result = 'ignored' - activity_log.exception_message = 'Create received for already known object' - db.session.commit() - return - else: - activity_log.activity_type = 'Update' - if can_edit(request_json['actor'], reply): - update_post_reply_from_activity(reply, request_json) - announce_activity_to_followers(reply.community, reply.author, request_json) - activity_log.result = 'success' - else: - activity_log.exception_message = 'Edit attempt denied' - else: - if community is None: # Mastodon: replies do not specify the community they're in. Attempt to find out the community by looking at the parent object - parent_post_id, parent_comment_id, _ = find_reply_parent(in_reply_to) - if parent_comment_id: - community = PostReply.query.get(parent_comment_id).community - elif parent_post_id: - community = Post.query.get(parent_post_id).community - if can_create_post_reply(user, community): - try: - post_reply = create_post_reply(activity_log, community, in_reply_to, request_json, user) - if post_reply: - announce_activity_to_followers(community, user, request_json) - except TypeError as e: - activity_log.exception_message = 'TypeError. See log file.' - current_app.logger.error('TypeError: ' + str(request_json)) - post = None - else: - post = None - elif object_type == 'Video': # PeerTube: editing a video (PT doesn't seem to Announce these) - post = Post.query.filter_by(ap_id=request_json['object']['id']).first() - activity_log.activity_type = 'Update' - if post: - if can_edit(request_json['actor'], post): - update_post_from_activity(post, request_json) - activity_log.result = 'success' - else: - activity_log.exception_message = 'Edit attempt denied' - else: - activity_log.exception_message = 'Post not found' - else: - activity_log.exception_message = 'Unacceptable type (create): ' + object_type - else: - if user is None or community is None: - activity_log.exception_message = 'Blocked or unfound user or community' - if user and user.is_local(): - activity_log.exception_message = 'Activity about local content which is already present' - activity_log.result = 'ignored' - - # Announce is new content and votes that happened on a remote server. - if request_json['type'] == 'Announce': - if isinstance(request_json['object'], str): # Mastodon, PeerTube, A.gup.pe - activity_log.activity_json = json.dumps(request_json) - activity_log.exception_message = 'invalid json?' - if 'actor' in request_json: - community = find_actor_or_create(request_json['actor'], community_only=True, create_if_not_found=False) - if community: - post = resolve_remote_post(request_json['object'], community.id, request_json['actor']) - elif request_json['object']['type'] == 'Create' or request_json['object']['type'] == 'Update': - activity_log.activity_type = request_json['object']['type'] - if 'object' in request_json and 'object' in request_json['object']: - if not ensure_domains_match(request_json['object']['object']): - activity_log.exception_message = 'Domains do not match' - activity_log.result = 'failure' - db.session.commit() - return - user_ap_id = request_json['object']['object']['attributedTo'] - try: - community_ap_id = request_json['object']['audience'] if 'audience' in request_json['object'] else request_json['actor'] - except KeyError: - activity_log.activity_type = 'exception' - db.session.commit() - return - community = find_actor_or_create(community_ap_id, community_only=True) - user = find_actor_or_create(user_ap_id) - if (user and not user.is_local()) and community: - user.last_seen = community.last_active = site.last_active = utcnow() - object_type = request_json['object']['object']['type'] - new_content_types = ['Page', 'Article', 'Link', 'Note'] - if object_type in new_content_types: # create a new post - in_reply_to = request_json['object']['object']['inReplyTo'] if 'inReplyTo' in \ - request_json['object']['object'] else None - if not in_reply_to: - post = Post.query.filter_by(ap_id=request_json['object']['object']['id']).first() - if post: - if request_json['object']['type'] == 'Create': - activity_log.result = 'ignored' - activity_log.exception_message = 'Create received for already known object' - db.session.commit() - return - else: - try: - update_post_from_activity(post, request_json['object']) - except KeyError: - activity_log.result = 'exception' - db.session.commit() - return - activity_log.result = 'success' - else: # activity was a Create, or an Update sent instead of a Create - if can_create_post(user, community): - post = create_post(activity_log, community, request_json['object'], user, announce_id=request_json['id']) - else: - post = None - else: - reply = PostReply.query.filter_by(ap_id=request_json['object']['object']['id']).first() - if reply: - if request_json['object']['type'] == 'Create': - activity_log.result = 'ignored' - activity_log.exception_message = 'Create received for already known object' - db.session.commit() - return - else: - try: - update_post_reply_from_activity(reply, request_json['object']) - except KeyError: - activity_log.result = 'exception' - db.session.commit() - return - activity_log.result = 'success' - else: # activity was a Create, or an Update sent instead of a Create - if can_create_post_reply(user, community): - post = create_post_reply(activity_log, community, in_reply_to, request_json['object'], user, announce_id=request_json['id']) - else: - post = None - else: - activity_log.exception_message = 'Unacceptable type: ' + object_type - else: - if user is None or community is None: - activity_log.exception_message = 'Blocked or unfound user or community' - if user and user.is_local(): - activity_log.exception_message = 'Activity about local content which is already present' - activity_log.result = 'ignored' - - elif request_json['object']['type'] == 'Like' or request_json['object']['type'] == 'EmojiReact': - activity_log.activity_type = request_json['object']['type'] - user_ap_id = request_json['object']['actor'] - liked_ap_id = request_json['object']['object'] - user = find_actor_or_create(user_ap_id) - liked = find_liked_object(liked_ap_id) - - if user is None: - activity_log.exception_message = 'Blocked or unfound user' - elif liked is None: - activity_log.exception_message = 'Unfound object ' + liked_ap_id - elif user.is_local(): - activity_log.exception_message = 'Activity about local content which is already present' - activity_log.result = 'ignored' - elif can_upvote(user, liked.community): - # insert into voted table - if liked is None: - activity_log.exception_message = 'Liked object not found' - elif liked is not None and isinstance(liked, (Post, PostReply)): - liked.vote(user, 'upvote') - activity_log.result = 'success' - else: - activity_log.exception_message = 'Could not detect type of like' - else: - activity_log.exception_message = 'Cannot upvote this' - activity_log.result = 'ignored' - - elif request_json['object']['type'] == 'Dislike': - activity_log.activity_type = request_json['object']['type'] - if site.enable_downvotes is False: - activity_log.exception_message = 'Dislike ignored because of allow_dislike setting' - else: - user_ap_id = request_json['object']['actor'] - liked_ap_id = request_json['object']['object'] - user = find_actor_or_create(user_ap_id) - disliked = find_liked_object(liked_ap_id) - if user is None: - activity_log.exception_message = 'Blocked or unfound user' - elif disliked is None: - activity_log.exception_message = 'Unfound object ' + liked_ap_id - elif user.is_local(): - activity_log.exception_message = 'Activity about local content which is already present' - activity_log.result = 'ignored' - elif can_downvote(user, disliked.community, site): - # insert into voted table - if disliked is None: - activity_log.exception_message = 'Liked object not found' - elif isinstance(disliked, (Post, PostReply)): - disliked.vote(user, 'downvote') - activity_log.result = 'success' - # todo: recalculate 'hotness' of liked post/reply - else: - activity_log.exception_message = 'Could not detect type of like' - else: - activity_log.exception_message = 'Cannot downvote this' - activity_log.result = 'ignored' - elif request_json['object']['type'] == 'Delete': - activity_log.activity_type = request_json['object']['type'] - user_ap_id = request_json['object']['actor'] - to_be_deleted_ap_id = request_json['object']['object'] - if isinstance(to_be_deleted_ap_id, dict): - activity_log.result = 'failure' - activity_log.exception_message = 'dict instead of string ' + str(to_be_deleted_ap_id) - else: - delete_post_or_comment(user_ap_id, to_be_deleted_ap_id, activity_log.id) - elif request_json['object']['type'] == 'Page': # Sent for Mastodon's benefit - activity_log.result = 'ignored' - activity_log.exception_message = 'Intended for Mastodon' - elif request_json['object']['type'] == 'Note': # Never sent? - activity_log.result = 'ignored' - activity_log.exception_message = 'Intended for Mastodon' - elif request_json['object']['type'] == 'Undo': - if request_json['object']['object']['type'] == 'Like' or request_json['object']['object']['type'] == 'Dislike': - activity_log.activity_type = request_json['object']['object']['type'] - user_ap_id = request_json['object']['actor'] - user = find_actor_or_create(user_ap_id) - post = None - comment = None - target_ap_id = request_json['object']['object']['object'] # object object object! - post = undo_vote(activity_log, comment, post, target_ap_id, user) - elif request_json['object']['object']['type'] == 'Delete': - if 'object' in request_json and 'object' in request_json['object']: - restore_post_or_comment(request_json['object']['object'], activity_log.id) - elif request_json['object']['object']['type'] == 'Block': - activity_log.activity_type = 'Undo User Ban' - deletor_ap_id = request_json['object']['object']['actor'] - user_ap_id = request_json['object']['object']['object'] - target = request_json['object']['object']['target'] - if target == request_json['actor'] and user_ap_id.startswith('https://' + current_app.config['SERVER_NAME']): - unban_local_user(deletor_ap_id, user_ap_id, target) - activity_log.result = 'success' - elif request_json['object']['object']['type'] == 'Lock' and 'object' in request_json['object']['object']: - activity_log.activity_type = 'Post Unlock' - mod_ap_id = request_json['object']['object']['actor'] - post_id = request_json['object']['object']['object'] - lock_post(mod_ap_id, post_id, True) - activity_log.result = 'success' - elif request_json['object']['type'] == 'Add' and 'target' in request_json['object']: - activity_log.activity_type = request_json['object']['type'] - target = request_json['object']['target'] - community = Community.query.filter_by(ap_public_url=request_json['actor']).first() - if community: - featured_url = community.ap_featured_url - moderators_url = community.ap_moderators_url - if target == featured_url: - post = Post.query.filter_by(ap_id=request_json['object']['object']).first() - if post: - post.sticky = True - activity_log.result = 'success' - if target == moderators_url: - user = find_actor_or_create(request_json['object']['object']) - if user: - existing_membership = CommunityMember.query.filter_by(community_id=community.id, user_id=user.id).first() - if existing_membership: - existing_membership.is_moderator = True - else: - new_membership = CommunityMember(community_id=community.id, user_id=user.id, is_moderator=True) - db.session.add(new_membership) - db.session.commit() - activity_log.result = 'success' - elif request_json['object']['type'] == 'Remove' and 'target' in request_json['object']: - activity_log.activity_type = request_json['object']['type'] - target = request_json['object']['target'] - community = Community.query.filter_by(ap_public_url=request_json['actor']).first() - if community: - featured_url = community.ap_featured_url - moderators_url = community.ap_moderators_url - if target == featured_url: - post = Post.query.filter_by(ap_id=request_json['object']['object']).first() - if post: - post.sticky = False - activity_log.result = 'success' - if target == moderators_url: - user = find_actor_or_create(request_json['object']['object'], create_if_not_found=False) - if user: - existing_membership = CommunityMember.query.filter_by(community_id=community.id, user_id=user.id).first() - if existing_membership: - existing_membership.is_moderator = False - activity_log.result = 'success' - elif request_json['object']['type'] == 'Block' and 'target' in request_json['object']: - activity_log.activity_type = 'User Ban' - deletor_ap_id = request_json['object']['actor'] - user_ap_id = request_json['object']['object'] - target = request_json['object']['target'] - remove_data = request_json['object']['removeData'] - if target == request_json['actor']: - if remove_data == True: - remove_data_from_banned_user(deletor_ap_id, user_ap_id, target) - if user_ap_id.startswith('https://' + current_app.config['SERVER_NAME']): - ban_local_user(deletor_ap_id, user_ap_id, target, request_json['object']) - activity_log.result = 'success' - elif request_json['object']['type'] == 'Lock' and 'object' in request_json['object']: - activity_log.activity_type = 'Post Lock' - mod_ap_id = request_json['object']['actor'] - post_id = request_json['object']['object'] - lock_post(mod_ap_id, post_id, False) - activity_log.result = 'success' - else: - activity_log.exception_message = 'Invalid type for Announce' - - # Follow: remote user wants to join/follow one of our communities - elif request_json['type'] == 'Follow': # Follow is when someone wants to join a community - user_ap_id = request_json['actor'] - community_ap_id = request_json['object'] - follow_id = request_json['id'] - user = find_actor_or_create(user_ap_id) - community = find_actor_or_create(community_ap_id, community_only=True) - if isinstance(community, Community): - if community and community.local_only and user: - activity_log.exception_message = 'Local only cannot be followed by remote users' - - # send reject message to deny the follow - reject = { - "@context": default_context(), - "actor": community.public_url(), - "to": [ - user.public_url() - ], - "object": { - "actor": user.public_url(), - "to": None, - "object": community.public_url(), - "type": "Follow", - "id": follow_id - }, - "type": "Reject", - "id": f"https://{current_app.config['SERVER_NAME']}/activities/reject/" + gibberish(32) - } - # Lemmy doesn't yet understand Reject/Follow, so send without worrying about response for now. - post_request(user.ap_inbox_url, reject, community.private_key, f"{community.public_url()}#main-key") - else: - if user is not None and community is not None: - # check if user is banned from this community - banned = CommunityBan.query.filter_by(user_id=user.id, community_id=community.id).first() - if banned is None: - user.last_seen = utcnow() - if community_membership(user, community) != SUBSCRIPTION_MEMBER: - member = CommunityMember(user_id=user.id, community_id=community.id) - db.session.add(member) - db.session.commit() - cache.delete_memoized(community_membership, user, community) - # send accept message to acknowledge the follow - accept = { - "@context": default_context(), - "actor": community.public_url(), - "to": [ - user.public_url() - ], - "object": { - "actor": user.public_url(), - "to": None, - "object": community.public_url(), - "type": "Follow", - "id": follow_id - }, - "type": "Accept", - "id": f"https://{current_app.config['SERVER_NAME']}/activities/accept/" + gibberish(32) - } - if post_request(user.ap_inbox_url, accept, community.private_key, f"{community.public_url()}#main-key") is True: - activity_log.result = 'success' - else: - activity_log.exception_message = 'Error sending Accept' - else: - activity_log.exception_message = 'user is banned from this community' - elif isinstance(community, User): # Pixelfed sends follow requests to the shared inbox, not the user inbox... - if current_app.debug: - process_user_follow_request(request_json, activity_log.id, user.id) - else: - process_user_follow_request.delay(request_json, activity_log.id, user.id) - # Accept: remote server is accepting our previous follow request - elif request_json['type'] == 'Accept': - if isinstance(request_json['object'], str): # a.gup.pe accepts using a string with the ID of the follow request - join_request_parts = request_json['object'].split('/') - join_request = CommunityJoinRequest.query.get(join_request_parts[-1]) - existing_membership = CommunityMember.query.filter_by(user_id=join_request.user_id, - community_id=join_request.community_id).first() - if not existing_membership: - member = CommunityMember(user_id=join_request.user_id, community_id=join_request.community_id) - db.session.add(member) - community.subscriptions_count += 1 - db.session.commit() - cache.delete_memoized(community_membership, User.query.get(join_request.user_id), Community.query.get(join_request.community_id)) - activity_log.result = 'success' - elif request_json['object']['type'] == 'Follow': - community_ap_id = request_json['actor'] - user_ap_id = request_json['object']['actor'] - user = find_actor_or_create(user_ap_id) - community = find_actor_or_create(community_ap_id, community_only=True) - if user and community: - join_request = CommunityJoinRequest.query.filter_by(user_id=user.id, community_id=community.id).first() - if join_request: - existing_membership = CommunityMember.query.filter_by(user_id=user.id, community_id=community.id).first() - if not existing_membership: - member = CommunityMember(user_id=user.id, community_id=community.id) - db.session.add(member) - community.subscriptions_count += 1 - db.session.commit() - activity_log.result = 'success' - cache.delete_memoized(community_membership, user, community) - - elif request_json['type'] == 'Undo': - if request_json['object']['type'] == 'Follow': # Unsubscribe from a community - community_ap_id = request_json['object']['object'] - user_ap_id = request_json['object']['actor'] - user = find_actor_or_create(user_ap_id) - community = find_actor_or_create(community_ap_id, community_only=True) - if user and community: - user.last_seen = utcnow() - member = CommunityMember.query.filter_by(user_id=user.id, community_id=community.id).first() - join_request = CommunityJoinRequest.query.filter_by(user_id=user.id, community_id=community.id).first() - if member: - db.session.delete(member) - community.subscriptions_count -= 1 - if join_request: - db.session.delete(join_request) - db.session.commit() - cache.delete_memoized(community_membership, user, community) - activity_log.result = 'success' - elif request_json['object']['type'] == 'Like': # Undoing an upvote or downvote - activity_log.activity_type = request_json['object']['type'] - user_ap_id = request_json['actor'] - user = find_actor_or_create(user_ap_id) - post = None - comment = None - target_ap_id = request_json['object']['object'] - post_or_comment = undo_vote(activity_log, comment, post, target_ap_id, user) - if post_or_comment: - announce_activity_to_followers(post_or_comment.community, user, request_json) - activity_log.result = 'success' - elif request_json['object']['type'] == 'Dislike': # Undoing a downvote - probably unused - activity_log.activity_type = request_json['object']['type'] - user_ap_id = request_json['actor'] - user = find_actor_or_create(user_ap_id) - post = None - comment = None - target_ap_id = request_json['object']['object'] - post_or_comment = undo_downvote(activity_log, comment, post, target_ap_id, user) - if post_or_comment: - announce_activity_to_followers(post_or_comment.community, user, request_json) - activity_log.result = 'success' - elif request_json['object']['type'] == 'Block': # Undoing a ban - activity_log.activity_type = 'Undo User Ban' - deletor_ap_id = request_json['object']['actor'] - user_ap_id = request_json['object']['object'] - target = request_json['object']['target'] - if user_ap_id.startswith('https://' + current_app.config['SERVER_NAME']): - unban_local_user(deletor_ap_id, user_ap_id, target) - activity_log.result = 'success' - elif request_json['object']['type'] == 'Delete': # undoing a delete - activity_log.activity_type = 'Restore' - post = Post.query.filter_by(ap_id=request_json['object']['object']).first() - if post: - deletor = find_actor_or_create(request_json['object']['actor'], create_if_not_found=False) - if deletor: - if post.author.id == deletor.id or post.community.is_moderator(deletor) or post.community.is_instance_admin(deletor): - post.deleted = False - post.deleted_by = None - post.author.post_count += 1 - post.community.post_count += 1 - announce_activity_to_followers(post.community, post.author, request_json) - db.session.commit() - activity_log.result = 'success' - else: - activity_log.exception_message = 'Restore attempt denied' - else: - activity_log.exception_message = 'Restorer did not already exist' - else: - reply = PostReply.query.filter_by(ap_id=request_json['object']['object']).first() - if reply: - deletor = find_actor_or_create(request_json['object']['actor'], create_if_not_found=False) - if deletor: - if reply.author.id == deletor.id or reply.community.is_moderator(deletor) or reply.community.is_instance_admin(deletor): - reply.deleted = False - reply.deleted_by = None - if not reply.author.bot: - reply.post.reply_count += 1 - reply.author.post_reply_count += 1 - announce_activity_to_followers(reply.community, reply.author, request_json) - db.session.commit() - activity_log.result = 'success' - else: - activity_log.exception_message = 'Restore attempt denied' - else: - activity_log.exception_message = 'Restorer did not already exist' - else: - activity_log.exception_message = 'Object not found, or object was not a post or a reply' - elif request_json['type'] == 'Delete': - if isinstance(request_json['object'], str): - ap_id = request_json['object'] # lemmy - else: - ap_id = request_json['object']['id'] # kbin - post = Post.query.filter_by(ap_id=ap_id).first() - # Delete post - if post: - deletor = find_actor_or_create(request_json['actor'], create_if_not_found=False) - if deletor: - if post.author.id == deletor.id or post.community.is_moderator(deletor) or post.community.is_instance_admin(deletor): - post.deleted = True - post.delted_by = deletor.id - post.author.post_count -= 1 - post.community.post_count -= 1 - if post.url and post.cross_posts is not None: - old_cross_posts = Post.query.filter(Post.id.in_(post.cross_posts)).all() - post.cross_posts.clear() - for ocp in old_cross_posts: - if ocp.cross_posts is not None: - ocp.cross_posts.remove(post.id) - announce_activity_to_followers(post.community, post.author, request_json) - db.session.commit() - activity_log.result = 'success' - else: - activity_log.exception_message = 'Delete attempt denied' - else: - activity_log.exception_message = 'Deletor did not already exist' - else: - # Delete PostReply - reply = PostReply.query.filter_by(ap_id=ap_id).first() - if reply: - deletor = find_actor_or_create(request_json['actor'], create_if_not_found=False) - if deletor: - if reply.author.id == deletor.id or reply.community.is_moderator(deletor) or reply.community.is_instance_admin(deletor): - reply.deleted = True - reply.deleted_by = deletor.id - if not reply.author.bot: - reply.post.reply_count -= 1 - reply.author.post_reply_count -= 1 - announce_activity_to_followers(reply.community, reply.author, request_json) - db.session.commit() - activity_log.result = 'success' - else: - activity_log.exception_message = 'Delete attempt denied' - else: - activity_log.exception_message = 'Deletor did not already exist' - else: - # Delete User - user = find_actor_or_create(ap_id, create_if_not_found=False) - if user: - user.deleted = True - user.delete_dependencies() - db.session.commit() - activity_log.result = 'success' - else: - activity_log.exception_message = 'Delete: cannot find ' + ap_id - - elif request_json['type'] == 'Like' or request_json['type'] == 'EmojiReact': # Upvote - activity_log.activity_type = request_json['type'] - user_ap_id = request_json['actor'] - user = find_actor_or_create(user_ap_id) - liked = find_liked_object(request_json['object']) - if user is None: - activity_log.exception_message = 'Blocked or unfound user' - elif liked is None: - activity_log.exception_message = 'Unfound object ' + request_json['object'] - elif user.is_local(): - activity_log.exception_message = 'Activity about local content which is already present' - activity_log.result = 'ignored' - elif can_upvote(user, liked.community): - # insert into voted table - if liked is None: - activity_log.exception_message = 'Liked object not found' - elif liked is not None and isinstance(liked, (Post, PostReply)): - liked.vote(user, 'upvote') - activity_log.result = 'success' - else: - activity_log.exception_message = 'Could not detect type of like' - if activity_log.result == 'success': - announce_activity_to_followers(liked.community, user, request_json) - else: - activity_log.exception_message = 'Cannot upvote this' - activity_log.result = 'ignored' - elif request_json['type'] == 'Dislike': # Downvote - if get_setting('allow_dislike', True) is False: - activity_log.exception_message = 'Dislike ignored because of allow_dislike setting' - else: - activity_log.activity_type = request_json['type'] - user_ap_id = request_json['actor'] - user = find_actor_or_create(user_ap_id) - target_ap_id = request_json['object'] - disliked = find_liked_object(target_ap_id) - if user is None: - activity_log.exception_message = 'Blocked or unfound user' - elif disliked is None: - activity_log.exception_message = 'Unfound object' + target_ap_id - elif user.is_local(): - activity_log.exception_message = 'Activity about local content which is already present' - activity_log.result = 'ignored' - elif can_downvote(user, disliked.community, site): - # insert into voted table - if disliked is None: - activity_log.exception_message = 'Liked object not found' - elif isinstance(disliked, (Post, PostReply)): - disliked.vote(user, 'downvote') - activity_log.result = 'success' - else: - activity_log.exception_message = 'Could not detect type of like' - if activity_log.result == 'success': - announce_activity_to_followers(disliked.community, user, request_json) - else: - activity_log.exception_message = 'Cannot downvote this' - activity_log.result = 'ignored' - elif request_json['type'] == 'Flag': # Reported content - activity_log.activity_type = 'Report' - user_ap_id = request_json['actor'] - user = find_actor_or_create(user_ap_id) - target_ap_id = request_json['object'] - reported = find_reported_object(target_ap_id) - if user and reported: - process_report(user, reported, request_json, activity_log) - announce_activity_to_followers(reported.community, user, request_json) - activity_log.result = 'success' - else: - activity_log.exception_message = 'Report ignored due to missing user or content' - elif request_json['type'] == 'Block': - activity_log.activity_type = 'User Ban' - deletor_ap_id = request_json['actor'] - user_ap_id = request_json['object'] - target = request_json['target'] - remove_data = request_json['removeData'] - if remove_data == True: - remove_data_from_banned_user(deletor_ap_id, user_ap_id, target) - if user_ap_id.startswith('https://' + current_app.config['SERVER_NAME']): - ban_local_user(deletor_ap_id, user_ap_id, target, request_json) - activity_log.result = 'success' - - # Flush the caches of any major object that was created. To be sure. - if 'user' in vars() and user is not None: - if user.instance_id and user.instance_id != 1: - user.instance.last_seen = utcnow() - # user.instance.ip_address = ip_address - user.instance.dormant = False - user.instance.gone_forever = False - user.instance.failures = 0 - else: - activity_log.exception_message = 'Instance blocked' - - if activity_log.exception_message is not None and activity_log.result == 'processing': - activity_log.result = 'failure' - # Don't log successful json - save space - if site.log_activitypub_json and activity_log.result == 'success' and not current_app.debug: - activity_log.activity_json = '' - db.session.commit() + log_incoming_ap(request_json['id'], APLOG_MONITOR, APLOG_PROCESSING, request_json if store_ap_json else None, 'Unmatched activity') @celery.task