make Protocol._targets use per-protocol blocklist check

pull/640/head
Ryan Barrett 2023-09-09 15:11:52 -07:00
rodzic 0d2e4fb66a
commit fd6e371635
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 6BE31FDF4776E9D4
4 zmienionych plików z 44 dodań i 8 usunięć

Wyświetl plik

@ -27,6 +27,7 @@ from urllib.parse import urljoin, urlparse
import common
from common import (
add,
DOMAIN_BLOCKLIST,
error,
USER_AGENT,
)

Wyświetl plik

@ -770,12 +770,10 @@ class Protocol:
}
"""
logger.info('Finding recipients and their targets')
candidates = sorted(id for id in as1.targets(obj.as1)
if not cls.is_blocklisted(id))
orig_obj = None
targets = {}
for id in candidates:
for id in sorted(as1.targets(obj.as1)):
protocol = Protocol.for_id(id)
if not protocol:
logger.info(f"Can't determine protocol for {id}")
@ -783,6 +781,9 @@ class Protocol:
elif protocol == cls and cls.LABEL != 'fake':
logger.info(f'Skipping same-protocol target {id}')
continue
elif protocol.is_blocklisted(id):
logger.info(f'{id} is blocklisted')
continue
orig_obj = protocol.load(id)
if not orig_obj or not orig_obj.as1:
@ -856,7 +857,7 @@ class Protocol:
feed_obj.put()
# de-dupe targets, discard same-domain and blocklisted
# de-dupe targets, discard same-domain
candidates = {t.uri: (t, obj) for t, obj in targets.items()}
targets = {}
source_domains = [
@ -865,9 +866,7 @@ class Protocol:
if util.is_web(url)
]
for url in sorted(util.dedupe_urls(candidates.keys())):
if cls.is_blocklisted(url):
logger.info(f'Skipping blocklisted target {url}')
elif util.is_web(url) and util.domain_from_link(url) in source_domains:
if util.is_web(url) and util.domain_from_link(url) in source_domains:
logger.info(f'Skipping same-domain target {url}')
else:
target, obj = candidates[url]

Wyświetl plik

@ -1,4 +1,5 @@
"""Unit tests for protocol.py."""
import copy
from unittest import skip
from unittest.mock import patch
@ -14,7 +15,8 @@ from .testutil import Fake, OtherFake, TestCase
from activitypub import ActivityPub
from app import app
from models import Follower, Object, PROTOCOLS, User
from atproto import ATProto
from models import Follower, Object, PROTOCOLS, Target, User
import protocol
from protocol import Protocol
from ui import UIProtocol
@ -22,6 +24,7 @@ from web import Web
from werkzeug.exceptions import BadRequest
from .test_activitypub import ACTOR
from .test_atproto import DID_DOC
from .test_web import ACTOR_HTML
@ -273,6 +276,35 @@ class ProtocolTest(TestCase):
self.assertEqual(a_key, Fake.actor_key(Object()))
self.assertIsNone(Fake.actor_key(Object(), default_g_user=False))
def test_targets_checks_blocklisted_per_protocol(self):
"""_targets should call the target protocol's is_blocklisted()."""
# non-ATProto account, ATProto target (PDS) is http://localhost,
# shouldn't be blocklisted
user = self.make_user(id='fake:user', cls=Fake, atproto_did='did:plc:foo')
did_doc = copy.deepcopy(DID_DOC)
did_doc['services']['atproto_pds']['endpoint'] = 'http://localhost/'
self.store_object(id='did:plc:foo', raw=did_doc)
# store Objects so we don't try to fetch them remotely
self.store_object(id='at://did:plc:foo/co.ll/post', our_as1={'foo': 'bar'})
self.store_object(id='fake:post', our_as1={'foo': 'baz'})
obj = Object(our_as1={
'id': 'other:reply',
'objectType': 'note',
'inReplyTo': [
'fake:post',
'fake:blocklisted-post',
'https://t.co/foo',
'http://localhost/post',
'at://did:plc:foo/co.ll/post',
],
})
self.assertCountEqual([
Target(protocol='fake', uri='fake:post:target'),
Target(protocol='atproto', uri='http://localhost/'),
], Protocol._targets(obj).keys())
class ProtocolReceiveTest(TestCase):

Wyświetl plik

@ -87,6 +87,10 @@ class Fake(User, protocol.Protocol):
return id.startswith('fake:') or id in cls.fetchable
@classmethod
def is_blocklisted(cls, url):
return url.startswith('fake:blocklisted')
@classmethod
def send(cls, obj, url, log_data=True):
logger.info(f'Fake.send {url}')