diff --git a/app/activitypub/routes.py b/app/activitypub/routes.py index 1edf25c7..71584311 100644 --- a/app/activitypub/routes.py +++ b/app/activitypub/routes.py @@ -398,14 +398,14 @@ def shared_inbox(): request_json = request.get_json(force=True) except werkzeug.exceptions.BadRequest as e: log_incoming_ap('', APLOG_NOTYPE, APLOG_FAILURE, None, 'Unable to parse json body: ' + e.description) - return '', 400 + return '', 200 g.site = Site.query.get(1) # g.site is not initialized by @app.before_request when request.path == '/inbox' store_ap_json = g.site.log_activitypub_json if not 'id' in request_json or not 'type' in request_json or not 'actor' in request_json or not 'object' in request_json: log_incoming_ap('', APLOG_NOTYPE, APLOG_FAILURE, request_json if store_ap_json else None, 'Missing minimum expected fields in JSON') - return '', 400 + return '', 200 id = request_json['id'] if request_json['type'] == 'Announce' and isinstance(request_json['object'], dict): @@ -415,16 +415,16 @@ def shared_inbox(): log_incoming_ap(request_json['id'], APLOG_ANNOUNCE, APLOG_IGNORED, request_json if store_ap_json else None, 'Intended for Mastodon') else: log_incoming_ap(request_json['id'], APLOG_ANNOUNCE, APLOG_FAILURE, request_json if store_ap_json else None, 'Missing minimum expected fields in JSON Announce object') - return '', 400 + return '', 200 if object['actor'].startswith('https://' + current_app.config['SERVER_NAME']): log_incoming_ap(object['id'], APLOG_DUPLICATE, APLOG_IGNORED, request_json if store_ap_json else None, 'Activity about local content which is already present') - return '', 400 + return '', 200 redis_client = get_redis_connection() if redis_client.exists(id): # Something is sending same activity multiple times, or Announcing as well as sending the same content log_incoming_ap(id, APLOG_DUPLICATE, APLOG_IGNORED, request_json if store_ap_json else None, 'Unnecessary retry attempt') - return '', 400 + return '', 200 redis_client.set(id, 1, ex=90) # Save the activity ID into redis, to avoid duplicate activities # Ignore unutilised PeerTube activity @@ -439,7 +439,7 @@ def shared_inbox(): actor = User.query.filter_by(ap_profile_id=request_json['actor'].lower()).first() if not actor: log_incoming_ap(request_json['id'], APLOG_DELETE, APLOG_IGNORED, request_json if store_ap_json else None, 'Does not exist here') - return '', 400 + return '', 200 else: actor.ap_fetched_at = utcnow() # use stored pubkey, don't try to re-fetch for next step (signature verification) db.session.commit() @@ -448,11 +448,11 @@ def shared_inbox(): if not actor: actor_name = request_json['actor'] log_incoming_ap(request_json['id'], APLOG_NOTYPE, APLOG_FAILURE, request_json if store_ap_json else None, f'Actor could not be found 1: {actor_name}') - return '', 400 + return '', 200 if actor.is_local(): # should be impossible (can be Announced back, but not sent without access to privkey) log_incoming_ap(request_json['id'], APLOG_NOTYPE, APLOG_FAILURE, request_json if store_ap_json else None, 'ActivityPub activity from a local actor') - return '', 400 + return '', 200 else: actor.instance.last_seen = utcnow() actor.instance.dormant = False @@ -577,7 +577,7 @@ def process_inbox_request(request_json, store_ap_json): # It's the actor who signed the request, and whose signature has been verified # Because of the earlier check, we know that they already exist, and so don't need to check again # Using actors from inner objects has a vulnerability to spoofing attacks (e.g. if 'attributedTo' doesn't match the 'Create' actor) - + announce_id = request_json['id'] if request_json['type'] == 'Announce' or request_json['type'] == 'Accept' or request_json['type'] == 'Reject': community_ap_id = request_json['actor'] community = find_actor_or_create(community_ap_id, community_only=True, create_if_not_found=False) @@ -601,19 +601,19 @@ def process_inbox_request(request_json, store_ap_json): follow_id = request_json['id'] target = find_actor_or_create(target_ap_id, create_if_not_found=False) if not target: - log_incoming_ap(request_json['id'], APLOG_FOLLOW, APLOG_FAILURE, request_json if store_ap_json else None, 'Could not find target of Follow') + log_incoming_ap(announce_id, APLOG_FOLLOW, APLOG_FAILURE, request_json if store_ap_json else None, 'Could not find target of Follow') return if isinstance(target, Community): community = target reject_follow = False if community.local_only: - log_incoming_ap(request_json['id'], APLOG_FOLLOW, APLOG_FAILURE, request_json if store_ap_json else None, 'Local only cannot be followed by remote users') + log_incoming_ap(announce_id, APLOG_FOLLOW, APLOG_FAILURE, request_json if store_ap_json else None, 'Local only cannot be followed by remote users') reject_follow = True else: # check if user is banned from this community user_banned = CommunityBan.query.filter_by(user_id=user.id, community_id=community.id).first() if user_banned: - log_incoming_ap(request_json['id'], APLOG_FOLLOW, APLOG_FAILURE, request_json if store_ap_json else None, 'Remote user has been banned') + log_incoming_ap(announce_id, APLOG_FOLLOW, APLOG_FAILURE, request_json if store_ap_json else None, 'Remote user has been banned') reject_follow = True if reject_follow: # send reject message to deny the follow @@ -632,13 +632,13 @@ def process_inbox_request(request_json, store_ap_json): "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)} post_request(user.ap_inbox_url, accept, community.private_key, f"{community.public_url()}#main-key") - log_incoming_ap(request_json['id'], APLOG_FOLLOW, APLOG_SUCCESS, request_json if store_ap_json else None) + log_incoming_ap(announce_id, APLOG_FOLLOW, APLOG_SUCCESS, request_json if store_ap_json else None) return elif isinstance(target, User): local_user = target remote_user = user if not local_user.is_local(): - log_incoming_ap(request_json['id'], APLOG_FOLLOW, APLOG_FAILURE, request_json if store_ap_json else None, 'Follow request for remote user received') + log_incoming_ap(announce_id, APLOG_FOLLOW, APLOG_FAILURE, request_json if store_ap_json else None, 'Follow request for remote user received') return existing_follower = UserFollower.query.filter_by(local_user_id=local_user.id, remote_user_id=remote_user.id).first() if not existing_follower: @@ -652,7 +652,7 @@ def process_inbox_request(request_json, store_ap_json): "object": {"actor": remote_user.public_url(), "to": None, "object": local_user.public_url(), "type": "Follow", "id": follow_id}, "type": "Accept", "id": f"https://{current_app.config['SERVER_NAME']}/activities/accept/" + gibberish(32)} post_request(remote_user.ap_inbox_url, accept, local_user.private_key, f"{local_user.public_url()}#main-key") - log_incoming_ap(request_json['id'], APLOG_FOLLOW, APLOG_SUCCESS, request_json if store_ap_json else None) + log_incoming_ap(announce_id, APLOG_FOLLOW, APLOG_SUCCESS, request_json if store_ap_json else None) return # Accept: remote server is accepting our previous follow request @@ -667,7 +667,7 @@ def process_inbox_request(request_json, store_ap_json): user_ap_id = request_json['object']['actor'] user = find_actor_or_create(user_ap_id, create_if_not_found=False) if not user: - log_incoming_ap(request_json['id'], APLOG_ACCEPT, APLOG_FAILURE, request_json if store_ap_json else None, 'Could not find recipient of Accept') + log_incoming_ap(announce_id, APLOG_ACCEPT, APLOG_FAILURE, request_json if store_ap_json else None, 'Could not find recipient of Accept') return join_request = CommunityJoinRequest.query.filter_by(user_id=user.id, community_id=community.id).first() if join_request: @@ -678,7 +678,7 @@ def process_inbox_request(request_json, store_ap_json): community.subscriptions_count += 1 db.session.commit() cache.delete_memoized(community_membership, user, community) - log_incoming_ap(request_json['id'], APLOG_ACCEPT, APLOG_SUCCESS, request_json if store_ap_json else None) + log_incoming_ap(announce_id, APLOG_ACCEPT, APLOG_SUCCESS, request_json if store_ap_json else None) return # Reject: remote server is rejecting our previous follow request @@ -687,7 +687,7 @@ def process_inbox_request(request_json, store_ap_json): user_ap_id = request_json['object']['actor'] user = find_actor_or_create(user_ap_id, create_if_not_found=False) if not user: - log_incoming_ap(request_json['id'], APLOG_ACCEPT, APLOG_FAILURE, request_json if store_ap_json else None, 'Could not find recipient of Reject') + log_incoming_ap(announce_id, APLOG_ACCEPT, APLOG_FAILURE, request_json if store_ap_json else None, 'Could not find recipient of Reject') return join_request = CommunityJoinRequest.query.filter_by(user_id=user.id, community_id=community.id).first() if join_request: @@ -697,7 +697,7 @@ def process_inbox_request(request_json, store_ap_json): db.session.delete(existing_membership) cache.delete_memoized(community_membership, user, community) db.session.commit() - log_incoming_ap(request_json['id'], APLOG_ACCEPT, APLOG_SUCCESS, request_json if store_ap_json else None) + log_incoming_ap(announce_id, APLOG_ACCEPT, APLOG_SUCCESS, request_json if store_ap_json else None) return # Create is new content. Update is often an edit, but Updates from Lemmy can also be new content @@ -708,10 +708,10 @@ def process_inbox_request(request_json, store_ap_json): recipient = find_actor_or_create(recipient_ap_id, create_if_not_found=False) if recipient and recipient.is_local(): if sender.created_recently() or sender.reputation <= -10: - log_incoming_ap(request_json['id'], APLOG_CHATMESSAGE, APLOG_FAILURE, request_json if store_ap_json else None, 'Sender not eligible to send') + log_incoming_ap(announce_id, APLOG_CHATMESSAGE, APLOG_FAILURE, request_json if store_ap_json else None, 'Sender not eligible to send') return elif recipient.has_blocked_user(sender.id) or recipient.has_blocked_instance(sender.instance_id): - log_incoming_ap(request_json['id'], APLOG_CHATMESSAGE, APLOG_FAILURE, request_json if store_ap_json else None, 'Sender blocked by recipient') + log_incoming_ap(announce_id, APLOG_CHATMESSAGE, APLOG_FAILURE, request_json if store_ap_json else None, 'Sender blocked by recipient') return else: # Find existing conversation to add to @@ -740,7 +740,7 @@ def process_inbox_request(request_json, store_ap_json): recipient.unread_notifications += 1 existing_conversation.read = False db.session.commit() - log_incoming_ap(request_json['id'], APLOG_CHATMESSAGE, APLOG_SUCCESS, request_json if store_ap_json else None) + log_incoming_ap(announce_id, APLOG_CHATMESSAGE, APLOG_SUCCESS, request_json if store_ap_json else None) return # inner object of Create is not a ChatMessage else: @@ -753,20 +753,20 @@ def process_inbox_request(request_json, store_ap_json): if poll_data and choice: poll_data.vote_for_choice(choice.id, user.id) db.session.commit() - log_incoming_ap(request_json['id'], APLOG_CREATE, APLOG_SUCCESS, request_json if store_ap_json else None) + log_incoming_ap(announce_id, APLOG_CREATE, APLOG_SUCCESS, request_json if store_ap_json else None) if post_being_replied_to.author.is_local(): inform_followers_of_post_update(post_being_replied_to.id, user.instance_id) return community_ap_id = find_community_ap_id(request_json) if not ensure_domains_match(request_json['object']): - log_incoming_ap(request_json['id'], APLOG_CREATE, APLOG_FAILURE, request_json if store_ap_json else None, 'Domains do not match') + log_incoming_ap(announce_id, APLOG_CREATE, APLOG_FAILURE, request_json if store_ap_json else None, 'Domains do not match') return community = find_actor_or_create(community_ap_id, community_only=True, create_if_not_found=False) if community_ap_id else None if community and community.local_only: - log_incoming_ap(request_json['id'], APLOG_CREATE, APLOG_FAILURE, request_json if store_ap_json else None, 'Remote Create in local_only community') + log_incoming_ap(announce_id, APLOG_CREATE, APLOG_FAILURE, request_json if store_ap_json else None, 'Remote Create in local_only community') return if not community: - log_incoming_ap(request_json['id'], APLOG_CREATE, APLOG_FAILURE, request_json if store_ap_json else None, 'Blocked or unfound community') + log_incoming_ap(announce_id, APLOG_CREATE, APLOG_FAILURE, request_json if store_ap_json else None, 'Blocked or unfound community') return object_type = request_json['object']['type'] @@ -779,16 +779,16 @@ def process_inbox_request(request_json, store_ap_json): if post: if user.id == post.user_id: update_post_from_activity(post, request_json) - log_incoming_ap(request_json['id'], APLOG_UPDATE, APLOG_SUCCESS, request_json if store_ap_json else None) + log_incoming_ap(announce_id, APLOG_UPDATE, APLOG_SUCCESS, request_json if store_ap_json else None) return else: - log_incoming_ap(request_json['id'], APLOG_UPDATE, APLOG_FAILURE, request_json if store_ap_json else None, 'Edit attempt denied') + log_incoming_ap(announce_id, APLOG_UPDATE, APLOG_FAILURE, request_json if store_ap_json else None, 'Edit attempt denied') return else: - log_incoming_ap(request_json['id'], APLOG_UPDATE, APLOG_FAILURE, request_json if store_ap_json else None, 'PeerTube post not found') + log_incoming_ap(announce_id, APLOG_UPDATE, APLOG_FAILURE, request_json if store_ap_json else None, 'PeerTube post not found') return else: - log_incoming_ap(request_json['id'], APLOG_CREATE, APLOG_FAILURE, request_json if store_ap_json else None, 'Unacceptable type (create): ' + object_type) + log_incoming_ap(announce_id, APLOG_CREATE, APLOG_FAILURE, request_json if store_ap_json else None, 'Unacceptable type (create): ' + object_type) return if request_json['type'] == 'Delete': @@ -800,12 +800,12 @@ def process_inbox_request(request_json, store_ap_json): if to_delete: if to_delete.deleted: - log_incoming_ap(request_json['id'], APLOG_DELETE, APLOG_IGNORED, request_json if store_ap_json else None, 'Activity about local content which is already deleted') + log_incoming_ap(announce_id, APLOG_DELETE, APLOG_IGNORED, request_json if store_ap_json else None, 'Activity about local content which is already deleted') else: delete_post_or_comment(user, to_delete, store_ap_json, request_json) announce_activity_to_followers(to_delete.community, user, request_json) else: - log_incoming_ap(request_json['id'], APLOG_DELETE, APLOG_FAILURE, request_json if store_ap_json else None, 'Delete: cannot find ' + ap_id) + log_incoming_ap(announce_id, APLOG_DELETE, APLOG_FAILURE, request_json if store_ap_json else None, 'Delete: cannot find ' + ap_id) return if request_json['type'] == 'Like' or request_json['type'] == 'EmojiReact': # Upvote @@ -814,7 +814,7 @@ def process_inbox_request(request_json, store_ap_json): if request_json['type'] == 'Dislike': # Downvote if site.enable_downvotes is False: - log_incoming_ap(request_json['id'], APLOG_DISLIKE, APLOG_IGNORED, request_json if store_ap_json else None, 'Dislike ignored because of allow_dislike setting') + log_incoming_ap(announce_id, APLOG_DISLIKE, APLOG_IGNORED, request_json if store_ap_json else None, 'Dislike ignored because of allow_dislike setting') return process_downvote(user, store_ap_json, request_json, announced=False) return @@ -823,10 +823,10 @@ def process_inbox_request(request_json, store_ap_json): reported = find_reported_object(request_json['object']) if reported: process_report(user, reported, request_json) - log_incoming_ap(request_json['id'], APLOG_REPORT, APLOG_SUCCESS, request_json if store_ap_json else None) + log_incoming_ap(announce_id, APLOG_REPORT, APLOG_SUCCESS, request_json if store_ap_json else None) announce_activity_to_followers(reported.community, user, request_json) else: - log_incoming_ap(request_json['id'], APLOG_REPORT, APLOG_IGNORED, request_json if store_ap_json else None, 'Report ignored due to missing content') + log_incoming_ap(announce_id, APLOG_REPORT, APLOG_IGNORED, request_json if store_ap_json else None, 'Report ignored due to missing content') return if request_json['type'] == 'Block': # remote site is banning one of their users @@ -836,7 +836,7 @@ def process_inbox_request(request_json, store_ap_json): if store_ap_json: request_json['cc'] = [] # cut very long list of instances if not blocked: - log_incoming_ap(request_json['id'], APLOG_USERBAN, APLOG_IGNORED, request_json if store_ap_json else None, 'Does not exist here') + log_incoming_ap(announce_id, APLOG_USERBAN, APLOG_IGNORED, request_json if store_ap_json else None, 'Does not exist here') return block_from_ap_id = request_json['target'] remove_data = request_json['removeData'] if 'removeData' in request_json else False @@ -845,18 +845,18 @@ def process_inbox_request(request_json, store_ap_json): # Banning remote users is hacked by banning them from every community of which they are a part # There's plans to change this in the future though. if not blocker.is_instance_admin() and not blocked.instance_id == blocker.instance_id: - log_incoming_ap(request_json['id'], APLOG_USERBAN, APLOG_FAILURE, request_json if store_ap_json else None, 'Does not have permission') + log_incoming_ap(announce_id, APLOG_USERBAN, APLOG_FAILURE, request_json if store_ap_json else None, 'Does not have permission') return # request_json includes 'expires' and 'endTime' (same thing) but nowhere to record this and check in future for end in ban. if remove_data == True: site_ban_remove_data(blocker.id, blocked) - log_incoming_ap(request_json['id'], APLOG_USERBAN, APLOG_SUCCESS, request_json if store_ap_json else None) + log_incoming_ap(announce_id, APLOG_USERBAN, APLOG_SUCCESS, request_json if store_ap_json else None) else: #blocked.banned = True # uncommented until there's a mechanism for processing ban expiry date #db.session.commit() - log_incoming_ap(request_json['id'], APLOG_USERBAN, APLOG_IGNORED, request_json if store_ap_json else None, 'Banned, but content retained') + log_incoming_ap(announce_id, APLOG_USERBAN, APLOG_IGNORED, request_json if store_ap_json else None, 'Banned, but content retained') return if request_json['type'] == 'Undo': @@ -874,7 +874,7 @@ def process_inbox_request(request_json, store_ap_json): db.session.delete(join_request) db.session.commit() cache.delete_memoized(community_membership, user, community) - log_incoming_ap(request_json['id'], APLOG_UNDO_FOLLOW, APLOG_SUCCESS, request_json if store_ap_json else None) + log_incoming_ap(announce_id, APLOG_UNDO_FOLLOW, APLOG_SUCCESS, request_json if store_ap_json else None) return if isinstance(target, User): local_user = target @@ -883,10 +883,10 @@ def process_inbox_request(request_json, store_ap_json): if follower: db.session.delete(follower) db.session.commit() - log_incoming_ap(request_json['id'], APLOG_UNDO_FOLLOW, APLOG_SUCCESS, request_json if store_ap_json else None) + log_incoming_ap(announce_id, APLOG_UNDO_FOLLOW, APLOG_SUCCESS, request_json if store_ap_json else None) return if not target: - log_incoming_ap(request_json['id'], APLOG_UNDO_FOLLOW, APLOG_FAILURE, request_json if store_ap_json else None, 'Unfound target') + log_incoming_ap(announce_id, APLOG_UNDO_FOLLOW, APLOG_FAILURE, request_json if store_ap_json else None, 'Unfound target') return if request_json['object']['type'] == 'Delete': # Restore something previously deleted @@ -903,12 +903,12 @@ def process_inbox_request(request_json, store_ap_json): to_restore = find_liked_object(ap_id) # a user or a mod/admin is undoing the delete of a post or reply if to_restore: if not to_restore.deleted: - log_incoming_ap(request_json['id'], APLOG_UNDO_DELETE, APLOG_IGNORED, request_json if store_ap_json else None, 'Activity about local content which is already restored') + log_incoming_ap(announce_id, APLOG_UNDO_DELETE, APLOG_IGNORED, request_json if store_ap_json else None, 'Activity about local content which is already restored') else: restore_post_or_comment(restorer, to_restore, store_ap_json, request_json) announce_activity_to_followers(to_restore.community, user, request_json) else: - log_incoming_ap(request_json['id'], APLOG_UNDO_DELETE, APLOG_FAILURE, request_json if store_ap_json else None, 'Undo delete: cannot find ' + ap_id) + log_incoming_ap(announce_id, APLOG_UNDO_DELETE, APLOG_FAILURE, request_json if store_ap_json else None, 'Undo delete: cannot find ' + ap_id) return if request_json['object']['type'] == 'Like' or request_json['object']['type'] == 'Dislike': # Undoing an upvote or downvote @@ -916,10 +916,10 @@ def process_inbox_request(request_json, store_ap_json): target_ap_id = request_json['object']['object'] post_or_comment = undo_vote(comment, post, target_ap_id, user) if post_or_comment: - log_incoming_ap(request_json['id'], APLOG_UNDO_VOTE, APLOG_SUCCESS, request_json if store_ap_json else None) + log_incoming_ap(announce_id, APLOG_UNDO_VOTE, APLOG_SUCCESS, request_json if store_ap_json else None) announce_activity_to_followers(post_or_comment.community, user, request_json) else: - log_incoming_ap(request_json['id'], APLOG_UNDO_VOTE, APLOG_FAILURE, request_json if store_ap_json else None, 'Unfound object ' + target_ap_id) + log_incoming_ap(announce_id, APLOG_UNDO_VOTE, APLOG_FAILURE, request_json if store_ap_json else None, 'Unfound object ' + target_ap_id) return if request_json['object']['type'] == 'Block': # remote site is unbanning one of their users @@ -930,18 +930,18 @@ def process_inbox_request(request_json, store_ap_json): request_json['cc'] = [] # cut very long list of instances request_json['object']['cc'] = [] if not unblocked: - log_incoming_ap(request_json['id'], APLOG_USERBAN, APLOG_IGNORED, request_json if store_ap_json else None, 'Does not exist here') + log_incoming_ap(announce_id, APLOG_USERBAN, APLOG_IGNORED, request_json if store_ap_json else None, 'Does not exist here') return unblock_from_ap_id = request_json['object']['target'] - if not unblocker.is_instance_admin() and not unblocked.instance_id == blocker.instance_id: - log_incoming_ap(request_json['id'], APLOG_USERBAN, APLOG_FAILURE, request_json if store_ap_json else None, 'Does not have permission') + if not unblocker.is_instance_admin() and not unblocked.instance_id == unblocker.instance_id: + log_incoming_ap(announce_id, APLOG_USERBAN, APLOG_FAILURE, request_json if store_ap_json else None, 'Does not have permission') return # (no removeData field in an undo/ban - cannot restore without knowing if deletion was part of ban, or different moderator action) #unblocked.banned = False # uncommented until there's a mechanism for processing ban expiry date #db.session.commit() - log_incoming_ap(request_json['id'], APLOG_UNDO_USERBAN, APLOG_SUCCESS, request_json if store_ap_json else None) + log_incoming_ap(announce_id, APLOG_UNDO_USERBAN, APLOG_SUCCESS, request_json if store_ap_json else None) return # Announce is new content and votes that happened on a remote server. @@ -949,15 +949,15 @@ def process_inbox_request(request_json, store_ap_json): if isinstance(request_json['object'], str): # Mastodon, PeerTube, A.gup.pe post = resolve_remote_post(request_json['object'], community.id, announce_actor=community.ap_profile_id, store_ap_json=store_ap_json) if post: - log_incoming_ap(request_json['id'], APLOG_ANNOUNCE, APLOG_SUCCESS, request_json) + log_incoming_ap(announce_id, APLOG_ANNOUNCE, APLOG_SUCCESS, request_json) else: - log_incoming_ap(request_json['id'], APLOG_ANNOUNCE, APLOG_FAILURE, request_json, 'Could not resolve post') + log_incoming_ap(announce_id, APLOG_ANNOUNCE, APLOG_FAILURE, request_json, 'Could not resolve post') return user_ap_id = request_json['object']['actor'] user = find_actor_or_create(user_ap_id) if not user or not isinstance(user, User): - log_incoming_ap(request_json['id'], APLOG_ANNOUNCE, APLOG_FAILURE, request_json, 'Blocked or unfound user for Announce object actor ' + user_ap_id) + log_incoming_ap(announce_id, APLOG_ANNOUNCE, APLOG_FAILURE, request_json, 'Blocked or unfound user for Announce object actor ' + user_ap_id) return user.last_seen = site.last_active = utcnow() @@ -976,9 +976,9 @@ def process_inbox_request(request_json, store_ap_json): # force refresh next time community is heard from community.ap_fetched_at = None db.session.commit() - log_incoming_ap(request_json['id'], APLOG_UPDATE, APLOG_SUCCESS, request_json if store_ap_json else None) + log_incoming_ap(announce_id, APLOG_UPDATE, APLOG_SUCCESS, request_json if store_ap_json else None) else: - log_incoming_ap(request_json['id'], APLOG_CREATE, APLOG_FAILURE, request_json if store_ap_json else None, 'Unacceptable type (create): ' + object_type) + log_incoming_ap(announce_id, APLOG_CREATE, APLOG_FAILURE, request_json if store_ap_json else None, 'Unacceptable type (create): ' + object_type) return if request_json['object']['type'] == 'Delete': # Announced Delete @@ -990,11 +990,11 @@ def process_inbox_request(request_json, store_ap_json): if to_delete: if to_delete.deleted: - log_incoming_ap(request_json['id'], APLOG_DELETE, APLOG_IGNORED, request_json if store_ap_json else None, 'Activity about local content which is already deleted') + log_incoming_ap(announce_id, APLOG_DELETE, APLOG_IGNORED, request_json if store_ap_json else None, 'Activity about local content which is already deleted') else: delete_post_or_comment(user, to_delete, store_ap_json, request_json) else: - log_incoming_ap(request_json['id'], APLOG_DELETE, APLOG_FAILURE, request_json if store_ap_json else None, 'Delete: cannot find ' + ap_id) + log_incoming_ap(announce_id, APLOG_DELETE, APLOG_FAILURE, request_json if store_ap_json else None, 'Delete: cannot find ' + ap_id) return if request_json['object']['type'] == 'Like' or request_json['object']['type'] == 'EmojiReact': # Announced Upvote @@ -1003,7 +1003,7 @@ def process_inbox_request(request_json, store_ap_json): if request_json['object']['type'] == 'Dislike': # Announced Downvote if site.enable_downvotes is False: - log_incoming_ap(request_json['id'], APLOG_DISLIKE, APLOG_IGNORED, request_json if store_ap_json else None, 'Dislike ignored because of allow_dislike setting') + log_incoming_ap(announce_id, APLOG_DISLIKE, APLOG_IGNORED, request_json if store_ap_json else None, 'Dislike ignored because of allow_dislike setting') return process_downvote(user, store_ap_json, request_json) return @@ -1012,9 +1012,9 @@ def process_inbox_request(request_json, store_ap_json): reported = find_reported_object(request_json['object']['object']) if reported: process_report(user, reported, request_json['object']) - log_incoming_ap(request_json['id'], APLOG_REPORT, APLOG_SUCCESS, request_json if store_ap_json else None) + log_incoming_ap(announce_id, APLOG_REPORT, APLOG_SUCCESS, request_json if store_ap_json else None) else: - log_incoming_ap(request_json['id'], APLOG_REPORT, APLOG_IGNORED, request_json if store_ap_json else None, 'Report ignored due to missing content') + log_incoming_ap(announce_id, APLOG_REPORT, APLOG_IGNORED, request_json if store_ap_json else None, 'Report ignored due to missing content') return if request_json['object']['type'] == 'Lock': # Announce of post lock @@ -1025,11 +1025,11 @@ def process_inbox_request(request_json, store_ap_json): if post.community.is_moderator(mod) or post.community.is_instance_admin(mod): post.comments_enabled = False db.session.commit() - log_incoming_ap(request_json['id'], APLOG_LOCK, APLOG_SUCCESS, request_json if store_ap_json else None) + log_incoming_ap(announce_id, APLOG_LOCK, APLOG_SUCCESS, request_json if store_ap_json else None) else: - log_incoming_ap(request_json['id'], APLOG_LOCK, APLOG_FAILURE, request_json if store_ap_json else None, 'Lock: Does not have permission') + log_incoming_ap(announce_id, APLOG_LOCK, APLOG_FAILURE, request_json if store_ap_json else None, 'Lock: Does not have permission') else: - log_incoming_ap(request_json['id'], APLOG_LOCK, APLOG_FAILURE, request_json if store_ap_json else None, 'Lock: post not found') + log_incoming_ap(announce_id, APLOG_LOCK, APLOG_FAILURE, request_json if store_ap_json else None, 'Lock: post not found') return if request_json['object']['type'] == 'Add': # Announce of adding mods or stickying a post @@ -1041,9 +1041,9 @@ def process_inbox_request(request_json, store_ap_json): if post: post.sticky = True db.session.commit() - log_incoming_ap(request_json['id'], APLOG_ADD, APLOG_SUCCESS, request_json if store_ap_json else None) + log_incoming_ap(announce_id, APLOG_ADD, APLOG_SUCCESS, request_json if store_ap_json else None) else: - log_incoming_ap(request_json['id'], APLOG_ADD, APLOG_FAILURE, request_json if store_ap_json else None, 'Cannot find: ' + request_json['object']['object']) + log_incoming_ap(announce_id, APLOG_ADD, APLOG_FAILURE, request_json if store_ap_json else None, 'Cannot find: ' + request_json['object']['object']) return if target == moderators_url: user = find_actor_or_create(request_json['object']['object']) @@ -1055,11 +1055,11 @@ def process_inbox_request(request_json, store_ap_json): new_membership = CommunityMember(community_id=community.id, user_id=user.id, is_moderator=True) db.session.add(new_membership) db.session.commit() - log_incoming_ap(request_json['id'], APLOG_ADD, APLOG_SUCCESS, request_json if store_ap_json else None) + log_incoming_ap(announce_id, APLOG_ADD, APLOG_SUCCESS, request_json if store_ap_json else None) else: - log_incoming_ap(request_json['id'], APLOG_ADD, APLOG_FAILURE, request_json if store_ap_json else None, 'Cannot find: ' + request_json['object']['object']) + log_incoming_ap(announce_id, APLOG_ADD, APLOG_FAILURE, request_json if store_ap_json else None, 'Cannot find: ' + request_json['object']['object']) return - log_incoming_ap(request_json['id'], APLOG_ADD, APLOG_FAILURE, request_json if store_ap_json else None, 'Unknown target for Add') + log_incoming_ap(announce_id, APLOG_ADD, APLOG_FAILURE, request_json if store_ap_json else None, 'Unknown target for Add') return if request_json['object']['type'] == 'Remove': # Announce of removing mods or unstickying a post @@ -1071,9 +1071,9 @@ def process_inbox_request(request_json, store_ap_json): if post: post.sticky = False db.session.commit() - log_incoming_ap(request_json['id'], APLOG_REMOVE, APLOG_SUCCESS, request_json if store_ap_json else None) + log_incoming_ap(announce_id, APLOG_REMOVE, APLOG_SUCCESS, request_json if store_ap_json else None) else: - log_incoming_ap(request_json['id'], APLOG_REMOVE, APLOG_FAILURE, request_json if store_ap_json else None, 'Cannot find: ' + target) + log_incoming_ap(announce_id, APLOG_REMOVE, APLOG_FAILURE, request_json if store_ap_json else None, 'Cannot find: ' + target) return if target == moderators_url: user = find_actor_or_create(request_json['object']['object'], create_if_not_found=False) @@ -1082,11 +1082,11 @@ def process_inbox_request(request_json, store_ap_json): if existing_membership: existing_membership.is_moderator = False db.session.commit() - log_incoming_ap(request_json['id'], APLOG_REMOVE, APLOG_SUCCESS, request_json if store_ap_json else None) + log_incoming_ap(announce_id, APLOG_REMOVE, APLOG_SUCCESS, request_json if store_ap_json else None) else: - log_incoming_ap(request_json['id'], APLOG_REMOVE, APLOG_FAILURE, request_json if store_ap_json else None, 'Cannot find: ' + request_json['object']['object']) + log_incoming_ap(announce_id, APLOG_REMOVE, APLOG_FAILURE, request_json if store_ap_json else None, 'Cannot find: ' + request_json['object']['object']) return - log_incoming_ap(request_json['id'], APLOG_REMOVE, APLOG_FAILURE, request_json if store_ap_json else None, 'Unknown target for Remove') + log_incoming_ap(announce_id, APLOG_REMOVE, APLOG_FAILURE, request_json if store_ap_json else None, 'Unknown target for Remove') return if request_json['object']['type'] == 'Block': # Announce of user ban. Mod is banning a user from a community, @@ -1094,19 +1094,19 @@ def process_inbox_request(request_json, store_ap_json): blocked_ap_id = request_json['object']['object'].lower() blocked = User.query.filter_by(ap_profile_id=blocked_ap_id).first() if not blocked: - log_incoming_ap(request_json['id'], APLOG_USERBAN, APLOG_IGNORED, request_json if store_ap_json else None, 'Does not exist here') + log_incoming_ap(announce_id, APLOG_USERBAN, APLOG_IGNORED, request_json if store_ap_json else None, 'Does not exist here') return remove_data = request_json['object']['removeData'] if 'removeData' in request_json['object'] else False if not community.is_moderator(blocker) and not community.is_instance_admin(blocker): - log_incoming_ap(request_json['id'], APLOG_USERBAN, APLOG_FAILURE, request_json if store_ap_json else None, 'Does not have permission') + log_incoming_ap(announce_id, APLOG_USERBAN, APLOG_FAILURE, request_json if store_ap_json else None, 'Does not have permission') return if remove_data == True: community_ban_remove_data(blocker.id, community.id, blocked) - log_incoming_ap(request_json['id'], APLOG_USERBAN, APLOG_SUCCESS, request_json if store_ap_json else None) + log_incoming_ap(announce_id, APLOG_USERBAN, APLOG_SUCCESS, request_json if store_ap_json else None) else: - log_incoming_ap(request_json['id'], APLOG_USERBAN, APLOG_IGNORED, request_json if store_ap_json else None, 'Banned, but content retained') + log_incoming_ap(announce_id, APLOG_USERBAN, APLOG_IGNORED, request_json if store_ap_json else None, 'Banned, but content retained') if blocked.is_local(): ban_local_user(blocker, blocked, community, request_json) @@ -1123,11 +1123,11 @@ def process_inbox_request(request_json, store_ap_json): to_restore = find_liked_object(ap_id) # a user or a mod/admin is undoing the delete of a post or reply if to_restore: if not to_restore.deleted: - log_incoming_ap(request_json['id'], APLOG_UNDO_DELETE, APLOG_IGNORED, request_json if store_ap_json else None, 'Content was not deleted') + log_incoming_ap(announce_id, APLOG_UNDO_DELETE, APLOG_IGNORED, request_json if store_ap_json else None, 'Content was not deleted') else: restore_post_or_comment(restorer, to_restore, store_ap_json, request_json) else: - log_incoming_ap(request_json['id'], APLOG_UNDO_DELETE, APLOG_FAILURE, request_json if store_ap_json else None, 'Undo delete: cannot find ' + ap_id) + log_incoming_ap(announce_id, APLOG_UNDO_DELETE, APLOG_FAILURE, request_json if store_ap_json else None, 'Undo delete: cannot find ' + ap_id) return if request_json['object']['object']['type'] == 'Like' or request_json['object']['object']['type'] == 'Dislike': # Announce of undo of upvote or downvote @@ -1135,9 +1135,9 @@ def process_inbox_request(request_json, store_ap_json): target_ap_id = request_json['object']['object']['object'] post_or_comment = undo_vote(comment, post, target_ap_id, user) if post_or_comment: - log_incoming_ap(request_json['id'], APLOG_UNDO_VOTE, APLOG_SUCCESS, request_json if store_ap_json else None) + log_incoming_ap(announce_id, APLOG_UNDO_VOTE, APLOG_SUCCESS, request_json if store_ap_json else None) else: - log_incoming_ap(request_json['id'], APLOG_UNDO_VOTE, APLOG_FAILURE, request_json if store_ap_json else None, 'Unfound object ' + target_ap_id) + log_incoming_ap(announce_id, APLOG_UNDO_VOTE, APLOG_FAILURE, request_json if store_ap_json else None, 'Unfound object ' + target_ap_id) return if request_json['object']['object']['type'] == 'Lock': # Announce of undo of post lock @@ -1148,11 +1148,11 @@ def process_inbox_request(request_json, store_ap_json): if post.community.is_moderator(mod) or post.community.is_instance_admin(mod): post.comments_enabled = True db.session.commit() - log_incoming_ap(request_json['id'], APLOG_LOCK, APLOG_SUCCESS, request_json if store_ap_json else None) + log_incoming_ap(announce_id, APLOG_LOCK, APLOG_SUCCESS, request_json if store_ap_json else None) else: - log_incoming_ap(request_json['id'], APLOG_LOCK, APLOG_FAILURE, request_json if store_ap_json else None, 'Lock: Does not have permission') + log_incoming_ap(announce_id, APLOG_LOCK, APLOG_FAILURE, request_json if store_ap_json else None, 'Lock: Does not have permission') else: - log_incoming_ap(request_json['id'], APLOG_LOCK, APLOG_FAILURE, request_json if store_ap_json else None, 'Lock: post not found') + log_incoming_ap(announce_id, APLOG_LOCK, APLOG_FAILURE, request_json if store_ap_json else None, 'Lock: post not found') return if request_json['object']['object']['type'] == 'Block': # Announce of undo of user ban. Mod is unbanning a user from a community, @@ -1160,20 +1160,20 @@ def process_inbox_request(request_json, store_ap_json): blocked_ap_id = request_json['object']['object']['object'].lower() blocked = User.query.filter_by(ap_profile_id=blocked_ap_id).first() if not blocked: - log_incoming_ap(request_json['id'], APLOG_USERBAN, APLOG_IGNORED, request_json if store_ap_json else None, 'Does not exist here') + log_incoming_ap(announce_id, APLOG_USERBAN, APLOG_IGNORED, request_json if store_ap_json else None, 'Does not exist here') return if not community.is_moderator(blocker) and not community.is_instance_admin(blocker): - log_incoming_ap(request_json['id'], APLOG_USERBAN, APLOG_FAILURE, request_json if store_ap_json else None, 'Does not have permission') + log_incoming_ap(announce_id, APLOG_USERBAN, APLOG_FAILURE, request_json if store_ap_json else None, 'Does not have permission') return if blocked.is_local(): unban_local_user(blocker, blocked, community, request_json) - log_incoming_ap(request_json['id'], APLOG_USERBAN, APLOG_SUCCESS, request_json if store_ap_json else None) + log_incoming_ap(announce_id, APLOG_USERBAN, APLOG_SUCCESS, request_json if store_ap_json else None) return - log_incoming_ap(request_json['id'], APLOG_MONITOR, APLOG_PROCESSING, request_json if store_ap_json else None, 'Unmatched activity') + log_incoming_ap(announce_id, APLOG_MONITOR, APLOG_PROCESSING, request_json if store_ap_json else None, 'Unmatched activity') @celery.task @@ -1453,6 +1453,7 @@ def activity_result(id): def process_new_content(user, community, store_ap_json, request_json, announced=True): + announce_id = request_json['id'] if not announced: in_reply_to = request_json['object']['inReplyTo'] if 'inReplyTo' in request_json['object'] else None ap_id = request_json['object']['id'] @@ -1468,93 +1469,95 @@ def process_new_content(user, community, store_ap_json, request_json, announced= post = Post.query.filter_by(ap_id=ap_id).first() if post: if activity_json['type'] == 'Create': - log_incoming_ap(request_json['id'], APLOG_CREATE, APLOG_FAILURE, request_json if store_ap_json else None, 'Create processed after Update') + log_incoming_ap(announce_id, APLOG_CREATE, APLOG_FAILURE, request_json if store_ap_json else None, 'Create processed after Update') return if user.id == post.user_id: update_post_from_activity(post, activity_json) - log_incoming_ap(request_json['id'], APLOG_UPDATE, APLOG_SUCCESS, request_json if store_ap_json else None) + log_incoming_ap(announce_id, APLOG_UPDATE, APLOG_SUCCESS, request_json if store_ap_json else None) if not announced: announce_activity_to_followers(post.community, post.author, request_json) return else: - log_incoming_ap(request_json['id'], APLOG_UPDATE, APLOG_FAILURE, request_json if store_ap_json else None, 'Edit attempt denied') + log_incoming_ap(announce_id, APLOG_UPDATE, APLOG_FAILURE, request_json if store_ap_json else None, 'Edit attempt denied') return else: if can_create_post(user, community): try: post = create_post(store_ap_json, community, activity_json, user, announce_id=announce_id) if post: - log_incoming_ap(request_json['id'], APLOG_CREATE, APLOG_SUCCESS, request_json if store_ap_json else None) + log_incoming_ap(announce_id, APLOG_CREATE, APLOG_SUCCESS, request_json if store_ap_json else None) if not announced: announce_activity_to_followers(community, user, request_json) return except TypeError as e: current_app.logger.error('TypeError: ' + str(request_json)) - log_incoming_ap(request_json['id'], APLOG_CREATE, APLOG_FAILURE, request_json if store_ap_json else None, 'TypeError. See log file.') + log_incoming_ap(announce_id, APLOG_CREATE, APLOG_FAILURE, request_json if store_ap_json else None, 'TypeError. See log file.') return else: - log_incoming_ap(request_json['id'], APLOG_CREATE, APLOG_FAILURE, request_json if store_ap_json else None, 'User cannot create post in Community') + log_incoming_ap(announce_id, APLOG_CREATE, APLOG_FAILURE, request_json if store_ap_json else None, 'User cannot create post in Community') return else: # Creating a reply / comment reply = PostReply.query.filter_by(ap_id=ap_id).first() if reply: if activity_json['type'] == 'Create': - log_incoming_ap(request_json['id'], APLOG_CREATE, APLOG_FAILURE, request_json if store_ap_json else None, 'Create processed after Update') + log_incoming_ap(announce_id, APLOG_CREATE, APLOG_FAILURE, request_json if store_ap_json else None, 'Create processed after Update') return if user.id == reply.user_id: update_post_reply_from_activity(reply, activity_json) - log_incoming_ap(request_json['id'], APLOG_UPDATE, APLOG_SUCCESS, request_json if store_ap_json else None) + log_incoming_ap(announce_id, APLOG_UPDATE, APLOG_SUCCESS, request_json if store_ap_json else None) if not announced: announce_activity_to_followers(reply.community, reply.author, request_json) return else: - log_incoming_ap(request_json['id'], APLOG_UPDATE, APLOG_FAILURE, request_json if store_ap_json else None, 'Edit attempt denied') + log_incoming_ap(announce_id, APLOG_UPDATE, APLOG_FAILURE, request_json if store_ap_json else None, 'Edit attempt denied') return else: if can_create_post_reply(user, community): try: reply = create_post_reply(store_ap_json, community, in_reply_to, activity_json, user, announce_id=announce_id) if reply: - log_incoming_ap(request_json['id'], APLOG_CREATE, APLOG_SUCCESS, request_json if store_ap_json else None) + log_incoming_ap(announce_id, APLOG_CREATE, APLOG_SUCCESS, request_json if store_ap_json else None) if not announced: announce_activity_to_followers(community, user, request_json) return except TypeError as e: current_app.logger.error('TypeError: ' + str(request_json)) - log_incoming_ap(request_json['id'], APLOG_CREATE, APLOG_FAILURE, request_json if store_ap_json else None, 'TypeError. See log file.') + log_incoming_ap(announce_id, APLOG_CREATE, APLOG_FAILURE, request_json if store_ap_json else None, 'TypeError. See log file.') return else: - log_incoming_ap(request_json['id'], APLOG_CREATE, APLOG_FAILURE, request_json if store_ap_json else None, 'User cannot create reply in Community') + log_incoming_ap(announce_id, APLOG_CREATE, APLOG_FAILURE, request_json if store_ap_json else None, 'User cannot create reply in Community') return def process_upvote(user, store_ap_json, request_json, announced=True): + announce_id = request_json['id'] ap_id = request_json['object'] if not announced else request_json['object']['object'] liked = find_liked_object(ap_id) if liked is None: - log_incoming_ap(request_json['id'], APLOG_LIKE, APLOG_FAILURE, request_json if store_ap_json else None, 'Unfound object ' + ap_id) + log_incoming_ap(announce_id, APLOG_LIKE, APLOG_FAILURE, request_json if store_ap_json else None, 'Unfound object ' + ap_id) return if can_upvote(user, liked.community): if isinstance(liked, (Post, PostReply)): liked.vote(user, 'upvote') - log_incoming_ap(request_json['id'], APLOG_LIKE, APLOG_SUCCESS, request_json if store_ap_json else None) + log_incoming_ap(announce_id, APLOG_LIKE, APLOG_SUCCESS, request_json if store_ap_json else None) if not announced: announce_activity_to_followers(liked.community, user, request_json) else: - log_incoming_ap(request_json['id'], APLOG_LIKE, APLOG_IGNORED, request_json if store_ap_json else None, 'Cannot upvote this') + log_incoming_ap(announce_id, APLOG_LIKE, APLOG_IGNORED, request_json if store_ap_json else None, 'Cannot upvote this') def process_downvote(user, store_ap_json, request_json, announced=True): + announce_id = request_json['id'] ap_id = request_json['object'] if not announced else request_json['object']['object'] liked = find_liked_object(ap_id) if liked is None: - log_incoming_ap(request_json['id'], APLOG_DISLIKE, APLOG_FAILURE, request_json if store_ap_json else None, 'Unfound object ' + ap_id) + log_incoming_ap(announce_id, APLOG_DISLIKE, APLOG_FAILURE, request_json if store_ap_json else None, 'Unfound object ' + ap_id) return if can_downvote(user, liked.community): if isinstance(liked, (Post, PostReply)): liked.vote(user, 'downvote') - log_incoming_ap(request_json['id'], APLOG_DISLIKE, APLOG_SUCCESS, request_json if store_ap_json else None) + log_incoming_ap(announce_id, APLOG_DISLIKE, APLOG_SUCCESS, request_json if store_ap_json else None) if not announced: announce_activity_to_followers(liked.community, user, request_json) else: - log_incoming_ap(request_json['id'], APLOG_DISLIKE, APLOG_IGNORED, request_json if store_ap_json else None, 'Cannot downvote this') + log_incoming_ap(announce_id, APLOG_DISLIKE, APLOG_IGNORED, request_json if store_ap_json else None, 'Cannot downvote this')