import logging
import uuid
import re
-import urllib.parse
import simplejson as json
import cgi
+from urllib.parse import urlsplit
from Crypto.PublicKey import RSA
from .database import DATABASE
from .http_debug import http_debug
pubkey = privkey.publickey()
DATABASE["actorKeys"] = {
- "publicKey": pubkey.exportKey('PEM'),
- "privateKey": privkey.exportKey('PEM')
+ "publicKey": pubkey.exportKey('PEM').decode('utf-8'),
+ "privateKey": privkey.exportKey('PEM').decode('utf-8')
}
async def push_message_to_actor(actor, message, our_key_id):
inbox = get_actor_inbox(actor)
- url = urllib.parse.urlsplit(inbox)
+ url = urlsplit(inbox)
# XXX: Digest
data = json.dumps(message)
async def follow_remote_actor(actor_uri):
- logging.info('following: %r', actor_uri)
-
actor = await fetch_actor(actor_uri)
+ if not actor:
+ logging.info('failed to fetch actor at: %r', actor_uri)
+ return
+
+ logging.info('following: %r', actor_uri)
message = {
"@context": "https://www.w3.org/ns/activitystreams",
async def unfollow_remote_actor(actor_uri):
- logging.info('unfollowing: %r', actor_uri)
-
actor = await fetch_actor(actor_uri)
+ if not actor:
+ logging.info('failed to fetch actor at: %r', actor_uri)
+ return
+
+ logging.info('unfollowing: %r', actor_uri)
message = {
"@context": "https://www.w3.org/ns/activitystreams",
return cgi.escape(no_tags)
-def distill_inboxes(actor):
+def distill_inboxes(actor, object_id):
global DATABASE
+ origin_hostname = urlsplit(object_id).hostname
+
inbox = get_actor_inbox(actor)
targets = [target for target in DATABASE.get('relay-list', []) if target != inbox]
+ targets = [target for target in targets if urlsplit(target).hostname != origin_hostname]
+ hostnames = [urlsplit(target).hostname for target in targets]
assert inbox not in targets
+ assert origin_hostname not in hostnames
return targets
logging.debug('>> already relayed %r as %r', object_id, CACHE[object_id])
return
- # don't relay mastodon announces -- causes LRP fake direction issues
- if data['type'] == 'Announce' and len(data.get('cc', [])) > 0:
- return
-
activity_id = "https://{}/activities/{}".format(request.host, uuid.uuid4())
message = {
"@context": "https://www.w3.org/ns/activitystreams",
"type": "Announce",
- "to": ["https://{}/actor/followers".format(request.host)],
+ "to": ["https://{}/followers".format(request.host)],
"actor": "https://{}/actor".format(request.host),
"object": object_id,
"id": activity_id
logging.debug('>> relay: %r', message)
- inboxes = distill_inboxes(actor)
+ inboxes = distill_inboxes(actor, object_id)
futures = [push_message_to_actor({'inbox': inbox}, message, 'https://{}/actor#main-key'.format(request.host)) for inbox in inboxes]
asyncio.ensure_future(asyncio.gather(*futures))
following = DATABASE.get('relay-list', [])
inbox = get_actor_inbox(actor)
- if urllib.parse.urlsplit(inbox).hostname in AP_CONFIG['blocked_instances']:
+ if urlsplit(inbox).hostname in AP_CONFIG['blocked_instances']:
return
if inbox not in following: