2020-04-03 17:15:33 +00:00
|
|
|
__filename__ = "outbox.py"
|
|
|
|
__author__ = "Bob Mottram"
|
|
|
|
__license__ = "AGPL3+"
|
2021-01-26 10:07:42 +00:00
|
|
|
__version__ = "1.2.0"
|
2020-04-03 17:15:33 +00:00
|
|
|
__maintainer__ = "Bob Mottram"
|
2021-09-10 16:14:50 +00:00
|
|
|
__email__ = "bob@libreserver.org"
|
2020-04-03 17:15:33 +00:00
|
|
|
__status__ = "Production"
|
2021-06-15 15:08:12 +00:00
|
|
|
__module_group__ = "Timeline"
|
2020-01-13 10:35:17 +00:00
|
|
|
|
|
|
|
import os
|
2020-11-28 12:01:24 +00:00
|
|
|
from shutil import copyfile
|
2021-12-28 16:56:57 +00:00
|
|
|
from session import create_session
|
2021-12-28 21:36:27 +00:00
|
|
|
from auth import create_password
|
2021-12-29 21:55:09 +00:00
|
|
|
from posts import is_image_media
|
2021-12-28 19:33:29 +00:00
|
|
|
from posts import outbox_message_create_wrap
|
2021-12-28 18:13:52 +00:00
|
|
|
from posts import save_post_to_box
|
2021-12-29 21:55:09 +00:00
|
|
|
from posts import send_to_followers_thread
|
|
|
|
from posts import send_to_named_addresses_thread
|
2021-12-26 17:12:07 +00:00
|
|
|
from utils import has_object_stringType
|
2021-12-26 11:29:40 +00:00
|
|
|
from utils import get_base_content_from_post
|
2021-12-26 10:57:03 +00:00
|
|
|
from utils import has_object_dict
|
2021-12-27 20:43:15 +00:00
|
|
|
from utils import get_local_network_addresses
|
2021-12-26 12:45:03 +00:00
|
|
|
from utils import get_full_domain
|
2021-12-27 11:20:57 +00:00
|
|
|
from utils import remove_id_ending
|
2021-12-27 19:05:25 +00:00
|
|
|
from utils import get_domain_from_actor
|
2021-12-27 21:42:08 +00:00
|
|
|
from utils import dangerous_markup
|
2021-12-26 12:07:40 +00:00
|
|
|
from utils import is_featured_writer
|
2021-12-26 15:13:34 +00:00
|
|
|
from utils import load_json
|
2021-12-26 14:47:21 +00:00
|
|
|
from utils import save_json
|
2021-12-26 12:02:29 +00:00
|
|
|
from utils import acct_dir
|
2021-12-26 10:19:59 +00:00
|
|
|
from utils import local_actor_url
|
2021-12-26 17:15:04 +00:00
|
|
|
from utils import has_actor
|
2021-12-28 21:55:38 +00:00
|
|
|
from blocking import is_blocked_domain
|
2021-12-29 21:55:09 +00:00
|
|
|
from blocking import outbox_block
|
|
|
|
from blocking import outbox_undo_block
|
|
|
|
from blocking import outbox_mute
|
|
|
|
from blocking import outbox_undo_mute
|
2021-12-28 21:36:27 +00:00
|
|
|
from media import replace_you_tube
|
|
|
|
from media import replace_twitter
|
2021-12-29 21:55:09 +00:00
|
|
|
from media import get_media_path
|
|
|
|
from media import create_media_dirs
|
|
|
|
from inbox import inbox_update_index
|
|
|
|
from announce import outbox_announce
|
|
|
|
from announce import outbox_undo_announce
|
|
|
|
from follow import outbox_undo_follow
|
2021-12-28 20:32:11 +00:00
|
|
|
from follow import follower_approval_active
|
2021-12-29 21:55:09 +00:00
|
|
|
from skills import outbox_skills
|
|
|
|
from availability import outbox_availability
|
|
|
|
from like import outbox_like
|
|
|
|
from like import outbox_undo_like
|
|
|
|
from reaction import outbox_reaction
|
|
|
|
from reaction import outbox_undo_reaction
|
|
|
|
from bookmarks import outbox_bookmark
|
|
|
|
from bookmarks import outbox_undo_bookmark
|
|
|
|
from delete import outbox_delete
|
|
|
|
from shares import outbox_share_upload
|
|
|
|
from shares import outbox_undo_share_upload
|
|
|
|
from webapp_post import individual_post_as_html
|
|
|
|
|
|
|
|
|
|
|
|
def _person_receive_update_outbox(recent_posts_cache: {},
|
|
|
|
base_dir: str, http_prefix: str,
|
|
|
|
nickname: str, domain: str, port: int,
|
|
|
|
message_json: {}, debug: bool) -> None:
|
2021-03-17 20:18:00 +00:00
|
|
|
""" Receive an actor update from c2s
|
|
|
|
For example, setting the PGP key from the desktop client
|
|
|
|
"""
|
|
|
|
# these attachments are updatable via c2s
|
|
|
|
updatableAttachments = ('PGP', 'OpenPGP', 'Email')
|
|
|
|
|
2021-12-25 23:51:19 +00:00
|
|
|
if not message_json.get('type'):
|
2021-03-17 20:18:00 +00:00
|
|
|
return
|
2021-12-25 23:51:19 +00:00
|
|
|
if not isinstance(message_json['type'], str):
|
2021-07-19 08:59:30 +00:00
|
|
|
if debug:
|
|
|
|
print('DEBUG: c2s actor update type is not a string')
|
|
|
|
return
|
2021-12-25 23:51:19 +00:00
|
|
|
if message_json['type'] != 'Update':
|
2021-03-17 20:18:00 +00:00
|
|
|
return
|
2021-12-26 17:12:07 +00:00
|
|
|
if not has_object_stringType(message_json, debug):
|
2021-03-17 20:18:00 +00:00
|
|
|
return
|
2021-12-25 23:51:19 +00:00
|
|
|
if not isinstance(message_json['object']['type'], str):
|
2021-07-19 08:59:30 +00:00
|
|
|
if debug:
|
|
|
|
print('DEBUG: c2s actor update object type is not a string')
|
|
|
|
return
|
2021-12-25 23:51:19 +00:00
|
|
|
if message_json['object']['type'] != 'Person':
|
2021-03-17 20:18:00 +00:00
|
|
|
if debug:
|
|
|
|
print('DEBUG: not a c2s actor update')
|
|
|
|
return
|
2021-12-25 23:51:19 +00:00
|
|
|
if not message_json.get('to'):
|
2021-03-17 20:18:00 +00:00
|
|
|
if debug:
|
|
|
|
print('DEBUG: c2s actor update has no "to" field')
|
|
|
|
return
|
2021-12-26 17:15:04 +00:00
|
|
|
if not has_actor(message_json, debug):
|
2021-03-17 20:18:00 +00:00
|
|
|
return
|
2021-12-25 23:51:19 +00:00
|
|
|
if not message_json.get('id'):
|
2021-03-17 20:18:00 +00:00
|
|
|
if debug:
|
|
|
|
print('DEBUG: c2s actor update has no id field')
|
|
|
|
return
|
2021-12-25 23:51:19 +00:00
|
|
|
if not isinstance(message_json['id'], str):
|
2021-07-19 08:59:30 +00:00
|
|
|
if debug:
|
|
|
|
print('DEBUG: c2s actor update id is not a string')
|
|
|
|
return
|
2021-12-26 12:45:03 +00:00
|
|
|
domain_full = get_full_domain(domain, port)
|
2021-12-26 10:19:59 +00:00
|
|
|
actor = local_actor_url(http_prefix, nickname, domain_full)
|
2021-12-25 23:51:19 +00:00
|
|
|
if len(message_json['to']) != 1:
|
2021-03-17 20:18:00 +00:00
|
|
|
if debug:
|
|
|
|
print('DEBUG: c2s actor update - to does not contain one actor ' +
|
2021-12-25 23:51:19 +00:00
|
|
|
str(message_json['to']))
|
2021-03-17 20:18:00 +00:00
|
|
|
return
|
2021-12-25 23:51:19 +00:00
|
|
|
if message_json['to'][0] != actor:
|
2021-03-17 20:18:00 +00:00
|
|
|
if debug:
|
|
|
|
print('DEBUG: c2s actor update - to does not contain actor ' +
|
2021-12-25 23:51:19 +00:00
|
|
|
str(message_json['to']) + ' ' + actor)
|
2021-03-17 20:18:00 +00:00
|
|
|
return
|
2021-12-25 23:51:19 +00:00
|
|
|
if not message_json['id'].startswith(actor + '#updates/'):
|
2021-03-17 20:18:00 +00:00
|
|
|
if debug:
|
|
|
|
print('DEBUG: c2s actor update - unexpected id ' +
|
2021-12-25 23:51:19 +00:00
|
|
|
message_json['id'])
|
2021-03-17 20:18:00 +00:00
|
|
|
return
|
2021-12-25 23:51:19 +00:00
|
|
|
updatedActorJson = message_json['object']
|
2021-03-17 20:18:00 +00:00
|
|
|
# load actor from file
|
2021-12-26 12:02:29 +00:00
|
|
|
actorFilename = acct_dir(base_dir, nickname, domain) + '.json'
|
2021-03-17 20:18:00 +00:00
|
|
|
if not os.path.isfile(actorFilename):
|
|
|
|
print('actorFilename not found: ' + actorFilename)
|
|
|
|
return
|
2021-12-26 15:13:34 +00:00
|
|
|
actor_json = load_json(actorFilename)
|
2021-12-26 10:29:52 +00:00
|
|
|
if not actor_json:
|
2021-03-17 20:18:00 +00:00
|
|
|
return
|
|
|
|
actorChanged = False
|
|
|
|
# update fields within actor
|
|
|
|
if 'attachment' in updatedActorJson:
|
|
|
|
for newPropertyValue in updatedActorJson['attachment']:
|
|
|
|
if not newPropertyValue.get('name'):
|
|
|
|
continue
|
|
|
|
if newPropertyValue['name'] not in updatableAttachments:
|
|
|
|
continue
|
|
|
|
if not newPropertyValue.get('type'):
|
|
|
|
continue
|
|
|
|
if not newPropertyValue.get('value'):
|
|
|
|
continue
|
|
|
|
if newPropertyValue['type'] != 'PropertyValue':
|
|
|
|
continue
|
2021-12-26 10:29:52 +00:00
|
|
|
if 'attachment' not in actor_json:
|
2021-07-13 21:59:53 +00:00
|
|
|
continue
|
|
|
|
found = False
|
2021-12-26 10:29:52 +00:00
|
|
|
for attachIdx in range(len(actor_json['attachment'])):
|
|
|
|
if actor_json['attachment'][attachIdx]['type'] != \
|
2021-07-13 21:59:53 +00:00
|
|
|
'PropertyValue':
|
|
|
|
continue
|
2021-12-26 10:29:52 +00:00
|
|
|
if actor_json['attachment'][attachIdx]['name'] != \
|
2021-07-13 21:59:53 +00:00
|
|
|
newPropertyValue['name']:
|
|
|
|
continue
|
|
|
|
else:
|
2021-12-26 10:29:52 +00:00
|
|
|
if actor_json['attachment'][attachIdx]['value'] != \
|
2021-07-13 21:59:53 +00:00
|
|
|
newPropertyValue['value']:
|
2021-12-26 10:29:52 +00:00
|
|
|
actor_json['attachment'][attachIdx]['value'] = \
|
2021-07-13 21:59:53 +00:00
|
|
|
newPropertyValue['value']
|
|
|
|
actorChanged = True
|
|
|
|
found = True
|
|
|
|
break
|
|
|
|
if not found:
|
2021-12-26 10:29:52 +00:00
|
|
|
actor_json['attachment'].append({
|
2021-07-13 21:59:53 +00:00
|
|
|
"name": newPropertyValue['name'],
|
|
|
|
"type": "PropertyValue",
|
|
|
|
"value": newPropertyValue['value']
|
|
|
|
})
|
|
|
|
actorChanged = True
|
2021-03-17 20:18:00 +00:00
|
|
|
# save actor to file
|
|
|
|
if actorChanged:
|
2021-12-26 14:47:21 +00:00
|
|
|
save_json(actor_json, actorFilename)
|
2021-03-17 20:18:00 +00:00
|
|
|
if debug:
|
|
|
|
print('actor saved: ' + actorFilename)
|
|
|
|
if debug:
|
2021-12-26 10:29:52 +00:00
|
|
|
print('New attachment: ' + str(actor_json['attachment']))
|
|
|
|
message_json['object'] = actor_json
|
2021-03-17 20:18:00 +00:00
|
|
|
if debug:
|
|
|
|
print('DEBUG: actor update via c2s - ' + nickname + '@' + domain)
|
|
|
|
|
|
|
|
|
2021-12-29 21:55:09 +00:00
|
|
|
def post_message_to_outbox(session, translate: {},
|
|
|
|
message_json: {}, postToNickname: str,
|
|
|
|
server, base_dir: str, http_prefix: str,
|
|
|
|
domain: str, domain_full: str,
|
|
|
|
onion_domain: str, i2p_domain: str, port: int,
|
|
|
|
recent_posts_cache: {}, followers_threads: [],
|
|
|
|
federation_list: [], send_threads: [],
|
|
|
|
postLog: [], cached_webfingers: {},
|
|
|
|
person_cache: {}, allow_deletion: bool,
|
|
|
|
proxy_type: str, version: str, debug: bool,
|
|
|
|
yt_replace_domain: str,
|
|
|
|
twitter_replacement_domain: str,
|
|
|
|
show_published_date_only: bool,
|
|
|
|
allow_local_network_access: bool,
|
|
|
|
city: str, system_language: str,
|
|
|
|
shared_items_federated_domains: [],
|
|
|
|
sharedItemFederationTokens: {},
|
|
|
|
low_bandwidth: bool,
|
|
|
|
signing_priv_key_pem: str,
|
|
|
|
peertube_instances: str, theme: str,
|
|
|
|
max_like_count: int,
|
|
|
|
max_recent_posts: int, cw_lists: {},
|
|
|
|
lists_enabled: str,
|
|
|
|
content_license_url: str) -> bool:
|
2020-01-13 10:35:17 +00:00
|
|
|
"""post is received by the outbox
|
|
|
|
Client to server message post
|
|
|
|
https://www.w3.org/TR/activitypub/#client-to-server-outbox-delivery
|
|
|
|
"""
|
2021-12-25 23:51:19 +00:00
|
|
|
if not message_json.get('type'):
|
2020-01-13 10:35:17 +00:00
|
|
|
if debug:
|
|
|
|
print('DEBUG: POST to outbox has no "type" parameter')
|
|
|
|
return False
|
2021-12-25 23:51:19 +00:00
|
|
|
if not message_json.get('object') and message_json.get('content'):
|
|
|
|
if message_json['type'] != 'Create':
|
2020-01-13 10:35:17 +00:00
|
|
|
# https://www.w3.org/TR/activitypub/#object-without-create
|
|
|
|
if debug:
|
|
|
|
print('DEBUG: POST to outbox - adding Create wrapper')
|
2021-12-25 23:51:19 +00:00
|
|
|
message_json = \
|
2021-12-28 19:33:29 +00:00
|
|
|
outbox_message_create_wrap(http_prefix,
|
|
|
|
postToNickname,
|
|
|
|
domain, port,
|
|
|
|
message_json)
|
2020-12-11 10:46:47 +00:00
|
|
|
|
|
|
|
# check that the outgoing post doesn't contain any markup
|
|
|
|
# which can be used to implement exploits
|
2021-12-26 10:57:03 +00:00
|
|
|
if has_object_dict(message_json):
|
2021-12-26 11:29:40 +00:00
|
|
|
contentStr = get_base_content_from_post(message_json, system_language)
|
2021-07-18 14:15:16 +00:00
|
|
|
if contentStr:
|
2021-12-27 21:42:08 +00:00
|
|
|
if dangerous_markup(contentStr, allow_local_network_access):
|
2021-06-22 15:45:59 +00:00
|
|
|
print('POST to outbox contains dangerous markup: ' +
|
2021-12-25 23:51:19 +00:00
|
|
|
str(message_json))
|
2021-06-22 15:45:59 +00:00
|
|
|
return False
|
2020-12-11 10:46:47 +00:00
|
|
|
|
2021-12-25 23:51:19 +00:00
|
|
|
if message_json['type'] == 'Create':
|
|
|
|
if not (message_json.get('id') and
|
|
|
|
message_json.get('type') and
|
|
|
|
message_json.get('actor') and
|
|
|
|
message_json.get('object') and
|
|
|
|
message_json.get('to')):
|
|
|
|
if not message_json.get('id'):
|
2020-01-13 12:45:27 +00:00
|
|
|
if debug:
|
2020-04-03 17:15:33 +00:00
|
|
|
print('DEBUG: POST to outbox - ' +
|
|
|
|
'Create does not have the id parameter ' +
|
2021-12-25 23:51:19 +00:00
|
|
|
str(message_json))
|
|
|
|
elif not message_json.get('id'):
|
2020-01-13 12:45:27 +00:00
|
|
|
if debug:
|
2020-04-03 17:15:33 +00:00
|
|
|
print('DEBUG: POST to outbox - ' +
|
|
|
|
'Create does not have the type parameter ' +
|
2021-12-25 23:51:19 +00:00
|
|
|
str(message_json))
|
|
|
|
elif not message_json.get('id'):
|
2020-01-13 12:45:27 +00:00
|
|
|
if debug:
|
2020-04-03 17:15:33 +00:00
|
|
|
print('DEBUG: POST to outbox - ' +
|
|
|
|
'Create does not have the actor parameter ' +
|
2021-12-25 23:51:19 +00:00
|
|
|
str(message_json))
|
|
|
|
elif not message_json.get('id'):
|
2020-01-13 12:45:27 +00:00
|
|
|
if debug:
|
2020-04-03 17:15:33 +00:00
|
|
|
print('DEBUG: POST to outbox - ' +
|
|
|
|
'Create does not have the object parameter ' +
|
2021-12-25 23:51:19 +00:00
|
|
|
str(message_json))
|
2020-01-13 12:45:27 +00:00
|
|
|
else:
|
|
|
|
if debug:
|
2020-04-03 17:15:33 +00:00
|
|
|
print('DEBUG: POST to outbox - ' +
|
|
|
|
'Create does not have the "to" parameter ' +
|
2021-12-25 23:51:19 +00:00
|
|
|
str(message_json))
|
2020-01-13 10:35:17 +00:00
|
|
|
return False
|
2021-02-15 10:06:49 +00:00
|
|
|
|
|
|
|
# actor should be a string
|
2021-12-25 23:51:19 +00:00
|
|
|
if not isinstance(message_json['actor'], str):
|
2021-02-15 10:06:49 +00:00
|
|
|
return False
|
|
|
|
|
|
|
|
# actor should look like a url
|
2021-12-25 23:51:19 +00:00
|
|
|
if '://' not in message_json['actor'] or \
|
|
|
|
'.' not in message_json['actor']:
|
2021-02-15 10:06:49 +00:00
|
|
|
return False
|
|
|
|
|
|
|
|
# sent by an actor on a local network address?
|
2021-12-25 18:54:50 +00:00
|
|
|
if not allow_local_network_access:
|
2021-12-27 20:43:15 +00:00
|
|
|
localNetworkPatternList = get_local_network_addresses()
|
2021-02-15 10:06:49 +00:00
|
|
|
for localNetworkPattern in localNetworkPatternList:
|
2021-12-25 23:51:19 +00:00
|
|
|
if localNetworkPattern in message_json['actor']:
|
2021-02-15 10:06:49 +00:00
|
|
|
return False
|
|
|
|
|
2021-12-27 19:05:25 +00:00
|
|
|
testDomain, testPort = get_domain_from_actor(message_json['actor'])
|
2021-12-26 12:45:03 +00:00
|
|
|
testDomain = get_full_domain(testDomain, testPort)
|
2021-12-28 21:55:38 +00:00
|
|
|
if is_blocked_domain(base_dir, testDomain):
|
2020-01-13 10:35:17 +00:00
|
|
|
if debug:
|
2021-12-25 23:51:19 +00:00
|
|
|
print('DEBUG: domain is blocked: ' + message_json['actor'])
|
2020-01-13 10:35:17 +00:00
|
|
|
return False
|
2020-01-15 11:06:40 +00:00
|
|
|
# replace youtube, so that google gets less tracking data
|
2021-12-28 21:36:27 +00:00
|
|
|
replace_you_tube(message_json, yt_replace_domain, system_language)
|
2021-09-18 17:08:14 +00:00
|
|
|
# replace twitter, so that twitter posts can be shown without
|
|
|
|
# having a twitter account
|
2021-12-28 21:36:27 +00:00
|
|
|
replace_twitter(message_json, twitter_replacement_domain,
|
|
|
|
system_language)
|
2020-01-13 10:35:17 +00:00
|
|
|
# https://www.w3.org/TR/activitypub/#create-activity-outbox
|
2021-12-25 23:51:19 +00:00
|
|
|
message_json['object']['attributedTo'] = message_json['actor']
|
|
|
|
if message_json['object'].get('attachment'):
|
2020-04-03 17:15:33 +00:00
|
|
|
attachmentIndex = 0
|
2021-12-25 23:51:19 +00:00
|
|
|
attach = message_json['object']['attachment'][attachmentIndex]
|
2020-04-03 17:15:33 +00:00
|
|
|
if attach.get('mediaType'):
|
|
|
|
fileExtension = 'png'
|
|
|
|
mediaTypeStr = \
|
|
|
|
attach['mediaType']
|
2020-11-28 20:52:13 +00:00
|
|
|
|
|
|
|
extensions = {
|
|
|
|
"jpeg": "jpg",
|
|
|
|
"gif": "gif",
|
2021-01-11 22:27:57 +00:00
|
|
|
"svg": "svg",
|
2020-11-28 20:52:13 +00:00
|
|
|
"webp": "webp",
|
|
|
|
"avif": "avif",
|
|
|
|
"audio/mpeg": "mp3",
|
|
|
|
"ogg": "ogg",
|
|
|
|
"mp4": "mp4",
|
|
|
|
"webm": "webm",
|
|
|
|
"ogv": "ogv"
|
|
|
|
}
|
|
|
|
for matchExt, ext in extensions.items():
|
|
|
|
if mediaTypeStr.endswith(matchExt):
|
|
|
|
fileExtension = ext
|
|
|
|
break
|
|
|
|
|
2020-04-03 17:15:33 +00:00
|
|
|
mediaDir = \
|
2021-12-25 16:17:53 +00:00
|
|
|
base_dir + '/accounts/' + \
|
2020-04-03 17:15:33 +00:00
|
|
|
postToNickname + '@' + domain
|
|
|
|
uploadMediaFilename = mediaDir + '/upload.' + fileExtension
|
2020-01-13 10:35:17 +00:00
|
|
|
if not os.path.isfile(uploadMediaFilename):
|
2021-12-25 23:51:19 +00:00
|
|
|
del message_json['object']['attachment']
|
2020-01-13 10:35:17 +00:00
|
|
|
else:
|
|
|
|
# generate a path for the uploaded image
|
2021-12-29 21:55:09 +00:00
|
|
|
mPath = get_media_path()
|
2020-04-03 17:15:33 +00:00
|
|
|
mediaPath = mPath + '/' + \
|
2021-12-28 21:36:27 +00:00
|
|
|
create_password(16).lower() + '.' + fileExtension
|
2021-12-29 21:55:09 +00:00
|
|
|
create_media_dirs(base_dir, mPath)
|
2021-12-25 16:17:53 +00:00
|
|
|
mediaFilename = base_dir + '/' + mediaPath
|
2020-01-13 10:35:17 +00:00
|
|
|
# move the uploaded image to its new path
|
2020-04-03 17:15:33 +00:00
|
|
|
os.rename(uploadMediaFilename, mediaFilename)
|
2020-01-13 10:35:17 +00:00
|
|
|
# change the url of the attachment
|
2020-04-03 17:15:33 +00:00
|
|
|
attach['url'] = \
|
2021-12-26 10:00:46 +00:00
|
|
|
http_prefix + '://' + domain_full + '/' + mediaPath
|
2021-10-12 18:20:40 +00:00
|
|
|
attach['url'] = \
|
|
|
|
attach['url'].replace('/media/',
|
|
|
|
'/system/' +
|
|
|
|
'media_attachments/files/')
|
2020-01-13 10:35:17 +00:00
|
|
|
|
2021-11-10 12:16:03 +00:00
|
|
|
permittedOutboxTypes = (
|
|
|
|
'Create', 'Announce', 'Like', 'EmojiReact', 'Follow', 'Undo',
|
|
|
|
'Update', 'Add', 'Remove', 'Block', 'Delete', 'Skill', 'Ignore'
|
|
|
|
)
|
2021-12-25 23:51:19 +00:00
|
|
|
if message_json['type'] not in permittedOutboxTypes:
|
2020-01-13 10:35:17 +00:00
|
|
|
if debug:
|
2021-12-25 23:51:19 +00:00
|
|
|
print('DEBUG: POST to outbox - ' + message_json['type'] +
|
2020-01-13 10:35:17 +00:00
|
|
|
' is not a permitted activity type')
|
|
|
|
return False
|
2021-12-25 23:51:19 +00:00
|
|
|
if message_json.get('id'):
|
2021-12-27 11:20:57 +00:00
|
|
|
post_id = remove_id_ending(message_json['id'])
|
2020-01-13 10:35:17 +00:00
|
|
|
if debug:
|
|
|
|
print('DEBUG: id attribute exists within POST to outbox')
|
|
|
|
else:
|
|
|
|
if debug:
|
|
|
|
print('DEBUG: No id attribute within POST to outbox')
|
2021-12-26 19:47:06 +00:00
|
|
|
post_id = None
|
2020-01-13 10:35:17 +00:00
|
|
|
if debug:
|
2021-12-28 18:13:52 +00:00
|
|
|
print('DEBUG: save_post_to_box')
|
2021-12-25 23:51:19 +00:00
|
|
|
if message_json['type'] != 'Upgrade':
|
2020-04-03 17:15:33 +00:00
|
|
|
outboxName = 'outbox'
|
2020-02-24 22:50:55 +00:00
|
|
|
|
2020-08-23 11:13:35 +00:00
|
|
|
# if this is a blog post or an event then save to its own box
|
2021-12-25 23:51:19 +00:00
|
|
|
if message_json['type'] == 'Create':
|
2021-12-26 10:57:03 +00:00
|
|
|
if has_object_dict(message_json):
|
2021-12-25 23:51:19 +00:00
|
|
|
if message_json['object'].get('type'):
|
|
|
|
if message_json['object']['type'] == 'Article':
|
2021-06-22 15:45:59 +00:00
|
|
|
outboxName = 'tlblogs'
|
2020-02-28 14:51:44 +00:00
|
|
|
|
2020-04-03 17:15:33 +00:00
|
|
|
savedFilename = \
|
2021-12-28 18:13:52 +00:00
|
|
|
save_post_to_box(base_dir,
|
|
|
|
http_prefix,
|
|
|
|
post_id,
|
|
|
|
postToNickname, domain_full,
|
|
|
|
message_json, outboxName)
|
2020-08-25 20:20:56 +00:00
|
|
|
if not savedFilename:
|
|
|
|
print('WARN: post not saved to outbox ' + outboxName)
|
|
|
|
return False
|
2020-11-27 10:13:09 +00:00
|
|
|
|
|
|
|
# save all instance blogs to the news actor
|
|
|
|
if postToNickname != 'news' and outboxName == 'tlblogs':
|
2020-11-28 12:13:04 +00:00
|
|
|
if '/' in savedFilename:
|
2021-12-26 12:07:40 +00:00
|
|
|
if is_featured_writer(base_dir, postToNickname, domain):
|
2021-02-13 11:37:02 +00:00
|
|
|
savedPostId = savedFilename.split('/')[-1]
|
|
|
|
blogsDir = \
|
2021-12-25 16:17:53 +00:00
|
|
|
base_dir + '/accounts/news@' + domain + '/tlblogs'
|
2021-02-13 11:37:02 +00:00
|
|
|
if not os.path.isdir(blogsDir):
|
|
|
|
os.mkdir(blogsDir)
|
|
|
|
copyfile(savedFilename, blogsDir + '/' + savedPostId)
|
2021-12-29 21:55:09 +00:00
|
|
|
inbox_update_index('tlblogs', base_dir,
|
|
|
|
'news@' + domain,
|
|
|
|
savedFilename, debug)
|
2020-11-28 12:01:24 +00:00
|
|
|
|
2020-11-28 12:13:04 +00:00
|
|
|
# clear the citations file if it exists
|
|
|
|
citationsFilename = \
|
2021-12-25 16:17:53 +00:00
|
|
|
base_dir + '/accounts/' + \
|
2020-11-28 12:13:04 +00:00
|
|
|
postToNickname + '@' + domain + '/.citations.txt'
|
|
|
|
if os.path.isfile(citationsFilename):
|
2021-09-05 10:17:43 +00:00
|
|
|
try:
|
|
|
|
os.remove(citationsFilename)
|
2021-11-25 18:42:38 +00:00
|
|
|
except OSError:
|
2021-12-29 21:55:09 +00:00
|
|
|
print('EX: post_message_to_outbox unable to delete ' +
|
2021-10-29 18:48:15 +00:00
|
|
|
citationsFilename)
|
2020-11-27 10:13:09 +00:00
|
|
|
|
2021-07-04 11:11:15 +00:00
|
|
|
# The following activity types get added to the index files
|
|
|
|
indexedActivities = (
|
|
|
|
'Create', 'Question', 'Note', 'EncryptedMessage', 'Article',
|
|
|
|
'Patch', 'Announce'
|
|
|
|
)
|
2021-12-25 23:51:19 +00:00
|
|
|
if message_json['type'] in indexedActivities:
|
2020-04-03 17:15:33 +00:00
|
|
|
indexes = [outboxName, "inbox"]
|
2020-08-25 17:28:29 +00:00
|
|
|
selfActor = \
|
2021-12-26 10:19:59 +00:00
|
|
|
local_actor_url(http_prefix, postToNickname, domain_full)
|
2020-02-28 14:51:44 +00:00
|
|
|
for boxNameIndex in indexes:
|
2020-08-25 20:20:56 +00:00
|
|
|
if not boxNameIndex:
|
|
|
|
continue
|
2021-03-06 21:32:27 +00:00
|
|
|
|
|
|
|
# should this also go to the media timeline?
|
|
|
|
if boxNameIndex == 'inbox':
|
2021-12-29 21:55:09 +00:00
|
|
|
if is_image_media(session, base_dir, http_prefix,
|
|
|
|
postToNickname, domain,
|
|
|
|
message_json,
|
|
|
|
translate,
|
|
|
|
yt_replace_domain,
|
|
|
|
twitter_replacement_domain,
|
|
|
|
allow_local_network_access,
|
|
|
|
recent_posts_cache, debug,
|
|
|
|
system_language,
|
|
|
|
domain_full, person_cache,
|
|
|
|
signing_priv_key_pem):
|
|
|
|
inbox_update_index('tlmedia', base_dir,
|
|
|
|
postToNickname + '@' + domain,
|
|
|
|
savedFilename, debug)
|
2021-03-06 21:32:27 +00:00
|
|
|
|
2020-08-25 14:43:13 +00:00
|
|
|
if boxNameIndex == 'inbox' and outboxName == 'tlblogs':
|
2020-02-28 14:51:44 +00:00
|
|
|
continue
|
2021-06-22 20:30:27 +00:00
|
|
|
|
2020-05-17 13:27:07 +00:00
|
|
|
# avoid duplicates of the message if already going
|
|
|
|
# back to the inbox of the same account
|
2021-12-25 23:51:19 +00:00
|
|
|
if selfActor not in message_json['to']:
|
2020-05-17 13:27:07 +00:00
|
|
|
# show sent post within the inbox,
|
|
|
|
# as is the typical convention
|
2021-12-29 21:55:09 +00:00
|
|
|
inbox_update_index(boxNameIndex, base_dir,
|
|
|
|
postToNickname + '@' + domain,
|
|
|
|
savedFilename, debug)
|
2021-09-03 11:30:23 +00:00
|
|
|
|
|
|
|
# regenerate the html
|
|
|
|
useCacheOnly = False
|
|
|
|
pageNumber = 1
|
|
|
|
showIndividualPostIcons = True
|
|
|
|
manuallyApproveFollowers = \
|
2021-12-28 20:32:11 +00:00
|
|
|
follower_approval_active(base_dir,
|
|
|
|
postToNickname, domain)
|
2021-12-29 21:55:09 +00:00
|
|
|
individual_post_as_html(signing_priv_key_pem,
|
|
|
|
False, recent_posts_cache,
|
|
|
|
max_recent_posts,
|
|
|
|
translate, pageNumber,
|
|
|
|
base_dir, session,
|
|
|
|
cached_webfingers,
|
|
|
|
person_cache,
|
|
|
|
postToNickname, domain, port,
|
|
|
|
message_json, None, True,
|
|
|
|
allow_deletion,
|
|
|
|
http_prefix, __version__,
|
|
|
|
boxNameIndex,
|
|
|
|
yt_replace_domain,
|
|
|
|
twitter_replacement_domain,
|
|
|
|
show_published_date_only,
|
|
|
|
peertube_instances,
|
|
|
|
allow_local_network_access,
|
|
|
|
theme, system_language,
|
|
|
|
max_like_count,
|
|
|
|
boxNameIndex != 'dm',
|
|
|
|
showIndividualPostIcons,
|
|
|
|
manuallyApproveFollowers,
|
|
|
|
False, True, useCacheOnly,
|
|
|
|
cw_lists, lists_enabled)
|
|
|
|
|
|
|
|
if outbox_announce(recent_posts_cache,
|
|
|
|
base_dir, message_json, debug):
|
2020-01-13 10:35:17 +00:00
|
|
|
if debug:
|
2020-04-03 17:15:33 +00:00
|
|
|
print('DEBUG: Updated announcements (shares) collection ' +
|
|
|
|
'for the post associated with the Announce activity')
|
2020-01-13 10:35:17 +00:00
|
|
|
if not server.session:
|
2020-06-24 09:04:58 +00:00
|
|
|
print('DEBUG: creating new session for c2s')
|
2021-12-28 16:56:57 +00:00
|
|
|
server.session = create_session(proxy_type)
|
2020-06-08 20:22:18 +00:00
|
|
|
if not server.session:
|
2021-12-29 21:55:09 +00:00
|
|
|
print('ERROR: Failed to create session for post_message_to_outbox')
|
2020-06-08 20:22:18 +00:00
|
|
|
return False
|
2020-01-13 10:35:17 +00:00
|
|
|
if debug:
|
|
|
|
print('DEBUG: sending c2s post to followers')
|
|
|
|
# remove inactive threads
|
2020-04-03 17:15:33 +00:00
|
|
|
inactiveFollowerThreads = []
|
2021-12-25 22:48:08 +00:00
|
|
|
for th in followers_threads:
|
2020-01-13 10:35:17 +00:00
|
|
|
if not th.is_alive():
|
|
|
|
inactiveFollowerThreads.append(th)
|
|
|
|
for th in inactiveFollowerThreads:
|
2021-12-25 22:48:08 +00:00
|
|
|
followers_threads.remove(th)
|
2020-01-13 10:35:17 +00:00
|
|
|
if debug:
|
2021-12-25 22:48:08 +00:00
|
|
|
print('DEBUG: ' + str(len(followers_threads)) +
|
2020-04-03 17:15:33 +00:00
|
|
|
' followers threads active')
|
2020-01-20 12:43:34 +00:00
|
|
|
# retain up to 200 threads
|
2021-12-25 22:48:08 +00:00
|
|
|
if len(followers_threads) > 200:
|
2020-01-13 10:35:17 +00:00
|
|
|
# kill the thread if it is still alive
|
2021-12-25 22:48:08 +00:00
|
|
|
if followers_threads[0].is_alive():
|
|
|
|
followers_threads[0].kill()
|
2020-01-13 10:35:17 +00:00
|
|
|
# remove it from the list
|
2021-12-25 22:48:08 +00:00
|
|
|
followers_threads.pop(0)
|
2020-01-13 10:35:17 +00:00
|
|
|
# create a thread to send the post to followers
|
2020-04-03 17:15:33 +00:00
|
|
|
followersThread = \
|
2021-12-29 21:55:09 +00:00
|
|
|
send_to_followers_thread(server.session,
|
|
|
|
base_dir,
|
|
|
|
postToNickname,
|
|
|
|
domain, onion_domain, i2p_domain,
|
|
|
|
port, http_prefix,
|
|
|
|
federation_list,
|
|
|
|
send_threads,
|
|
|
|
postLog,
|
|
|
|
cached_webfingers,
|
|
|
|
person_cache,
|
|
|
|
message_json, debug,
|
|
|
|
version,
|
|
|
|
shared_items_federated_domains,
|
|
|
|
sharedItemFederationTokens,
|
|
|
|
signing_priv_key_pem)
|
2021-12-25 22:48:08 +00:00
|
|
|
followers_threads.append(followersThread)
|
2020-02-04 20:11:19 +00:00
|
|
|
|
2020-01-13 10:35:17 +00:00
|
|
|
if debug:
|
|
|
|
print('DEBUG: handle any unfollow requests')
|
2021-12-29 21:55:09 +00:00
|
|
|
outbox_undo_follow(base_dir, message_json, debug)
|
2020-02-04 20:11:19 +00:00
|
|
|
|
2020-01-13 10:35:17 +00:00
|
|
|
if debug:
|
|
|
|
print('DEBUG: handle skills changes requests')
|
2021-12-29 21:55:09 +00:00
|
|
|
outbox_skills(base_dir, postToNickname, message_json, debug)
|
2020-02-04 20:11:19 +00:00
|
|
|
|
2020-01-13 10:35:17 +00:00
|
|
|
if debug:
|
|
|
|
print('DEBUG: handle availability changes requests')
|
2021-12-29 21:55:09 +00:00
|
|
|
outbox_availability(base_dir, postToNickname, message_json, debug)
|
2020-01-13 10:35:17 +00:00
|
|
|
|
|
|
|
if debug:
|
|
|
|
print('DEBUG: handle any like requests')
|
2021-12-29 21:55:09 +00:00
|
|
|
outbox_like(recent_posts_cache,
|
|
|
|
base_dir, http_prefix,
|
|
|
|
postToNickname, domain, port,
|
|
|
|
message_json, debug)
|
2020-01-13 10:35:17 +00:00
|
|
|
if debug:
|
|
|
|
print('DEBUG: handle any undo like requests')
|
2021-12-29 21:55:09 +00:00
|
|
|
outbox_undo_like(recent_posts_cache,
|
|
|
|
base_dir, http_prefix,
|
|
|
|
postToNickname, domain, port,
|
|
|
|
message_json, debug)
|
2021-11-10 12:16:03 +00:00
|
|
|
|
|
|
|
if debug:
|
|
|
|
print('DEBUG: handle any emoji reaction requests')
|
2021-12-29 21:55:09 +00:00
|
|
|
outbox_reaction(recent_posts_cache,
|
|
|
|
base_dir, http_prefix,
|
|
|
|
postToNickname, domain, port,
|
|
|
|
message_json, debug)
|
2021-11-10 12:16:03 +00:00
|
|
|
if debug:
|
|
|
|
print('DEBUG: handle any undo emoji reaction requests')
|
2021-12-29 21:55:09 +00:00
|
|
|
outbox_undo_reaction(recent_posts_cache,
|
|
|
|
base_dir, http_prefix,
|
|
|
|
postToNickname, domain, port,
|
|
|
|
message_json, debug)
|
2021-11-10 12:16:03 +00:00
|
|
|
|
2021-05-08 13:14:52 +00:00
|
|
|
if debug:
|
|
|
|
print('DEBUG: handle any undo announce requests')
|
2021-12-29 21:55:09 +00:00
|
|
|
outbox_undo_announce(recent_posts_cache,
|
|
|
|
base_dir, http_prefix,
|
|
|
|
postToNickname, domain, port,
|
|
|
|
message_json, debug)
|
2020-01-13 10:35:17 +00:00
|
|
|
|
|
|
|
if debug:
|
|
|
|
print('DEBUG: handle any bookmark requests')
|
2021-12-29 21:55:09 +00:00
|
|
|
outbox_bookmark(recent_posts_cache,
|
|
|
|
base_dir, http_prefix,
|
|
|
|
postToNickname, domain, port,
|
|
|
|
message_json, debug)
|
2020-01-13 10:35:17 +00:00
|
|
|
if debug:
|
|
|
|
print('DEBUG: handle any undo bookmark requests')
|
2021-12-29 21:55:09 +00:00
|
|
|
outbox_undo_bookmark(recent_posts_cache,
|
|
|
|
base_dir, http_prefix,
|
|
|
|
postToNickname, domain, port,
|
|
|
|
message_json, debug)
|
2020-01-13 10:35:17 +00:00
|
|
|
|
|
|
|
if debug:
|
2020-03-22 21:16:02 +00:00
|
|
|
print('DEBUG: handle delete requests')
|
2021-12-29 21:55:09 +00:00
|
|
|
outbox_delete(base_dir, http_prefix,
|
|
|
|
postToNickname, domain,
|
|
|
|
message_json, debug,
|
|
|
|
allow_deletion,
|
|
|
|
recent_posts_cache)
|
2020-02-04 20:11:19 +00:00
|
|
|
|
2020-01-13 10:35:17 +00:00
|
|
|
if debug:
|
|
|
|
print('DEBUG: handle block requests')
|
2021-12-29 21:55:09 +00:00
|
|
|
outbox_block(base_dir, http_prefix,
|
|
|
|
postToNickname, domain,
|
|
|
|
port,
|
|
|
|
message_json, debug)
|
2020-02-04 20:11:19 +00:00
|
|
|
|
2020-01-13 10:35:17 +00:00
|
|
|
if debug:
|
|
|
|
print('DEBUG: handle undo block requests')
|
2021-12-29 21:55:09 +00:00
|
|
|
outbox_undo_block(base_dir, http_prefix,
|
|
|
|
postToNickname, domain,
|
|
|
|
port, message_json, debug)
|
2020-02-04 20:11:19 +00:00
|
|
|
|
2021-03-20 21:20:41 +00:00
|
|
|
if debug:
|
|
|
|
print('DEBUG: handle mute requests')
|
2021-12-29 21:55:09 +00:00
|
|
|
outbox_mute(base_dir, http_prefix,
|
|
|
|
postToNickname, domain,
|
|
|
|
port,
|
|
|
|
message_json, debug,
|
|
|
|
recent_posts_cache)
|
2021-03-20 21:20:41 +00:00
|
|
|
|
|
|
|
if debug:
|
|
|
|
print('DEBUG: handle undo mute requests')
|
2021-12-29 21:55:09 +00:00
|
|
|
outbox_undo_mute(base_dir, http_prefix,
|
|
|
|
postToNickname, domain,
|
|
|
|
port,
|
|
|
|
message_json, debug,
|
|
|
|
recent_posts_cache)
|
2021-03-20 21:20:41 +00:00
|
|
|
|
2020-01-13 10:35:17 +00:00
|
|
|
if debug:
|
|
|
|
print('DEBUG: handle share uploads')
|
2021-12-29 21:55:09 +00:00
|
|
|
outbox_share_upload(base_dir, http_prefix, postToNickname, domain,
|
|
|
|
port, message_json, debug, city,
|
|
|
|
system_language, translate, low_bandwidth,
|
|
|
|
content_license_url)
|
2020-02-04 20:11:19 +00:00
|
|
|
|
2020-01-13 10:35:17 +00:00
|
|
|
if debug:
|
|
|
|
print('DEBUG: handle undo share uploads')
|
2021-12-29 21:55:09 +00:00
|
|
|
outbox_undo_share_upload(base_dir, http_prefix,
|
|
|
|
postToNickname, domain,
|
|
|
|
port, message_json, debug)
|
2020-02-04 20:11:19 +00:00
|
|
|
|
2021-03-17 20:18:00 +00:00
|
|
|
if debug:
|
|
|
|
print('DEBUG: handle actor updates from c2s')
|
2021-12-29 21:55:09 +00:00
|
|
|
_person_receive_update_outbox(recent_posts_cache,
|
|
|
|
base_dir, http_prefix,
|
|
|
|
postToNickname, domain, port,
|
|
|
|
message_json, debug)
|
2021-03-17 20:18:00 +00:00
|
|
|
|
2020-01-13 10:35:17 +00:00
|
|
|
if debug:
|
|
|
|
print('DEBUG: sending c2s post to named addresses')
|
2021-12-25 23:51:19 +00:00
|
|
|
if message_json.get('to'):
|
2020-04-03 17:15:33 +00:00
|
|
|
print('c2s sender: ' +
|
|
|
|
postToNickname + '@' + domain + ':' + str(port) +
|
2021-12-25 23:51:19 +00:00
|
|
|
' recipient: ' + str(message_json['to']))
|
2020-02-04 20:11:19 +00:00
|
|
|
else:
|
2020-04-03 17:15:33 +00:00
|
|
|
print('c2s sender: ' +
|
|
|
|
postToNickname + '@' + domain + ':' + str(port))
|
2021-10-20 20:00:09 +00:00
|
|
|
namedAddressesThread = \
|
2021-12-29 21:55:09 +00:00
|
|
|
send_to_named_addresses_thread(server.session, base_dir,
|
|
|
|
postToNickname,
|
|
|
|
domain, onion_domain, i2p_domain, port,
|
|
|
|
http_prefix,
|
|
|
|
federation_list,
|
|
|
|
send_threads,
|
|
|
|
postLog,
|
|
|
|
cached_webfingers,
|
|
|
|
person_cache,
|
|
|
|
message_json, debug,
|
|
|
|
version,
|
|
|
|
shared_items_federated_domains,
|
|
|
|
sharedItemFederationTokens,
|
|
|
|
signing_priv_key_pem)
|
2021-12-25 22:48:08 +00:00
|
|
|
followers_threads.append(namedAddressesThread)
|
2020-01-13 10:35:17 +00:00
|
|
|
return True
|