activitypub and salmon: return 501 on unsupported activity type

pull/27/head
Ryan Barrett 2017-10-16 22:21:13 -07:00
rodzic 02f1e67cf9
commit bf0897ba81
4 zmienionych plików z 70 dodań i 9 usunięć

Wyświetl plik

@ -21,7 +21,15 @@ CONTENT_TYPE_AS = 'application/activity+json'
CONNEG_HEADER = {
'Accept': '%s; q=0.9, %s; q=0.8' % (CONTENT_TYPE_AS2, CONTENT_TYPE_AS),
}
SUPPORTED_TYPES = (
'Announce',
'Article',
'Audio',
'Image',
'Like',
'Note',
'Video',
)
class ActorHandler(webapp2.RequestHandler):
"""Serves /[DOMAIN], fetches its mf2, converts to AS Actor, and serves it."""
@ -64,10 +72,13 @@ class InboxHandler(webapp2.RequestHandler):
try:
activity = json.loads(self.request.body)
assert activity
except (TypeError, ValueError, AssertionError):
msg = "Couldn't parse body as JSON"
logging.error(msg, exc_info=True)
common.error(self, msg)
except (TypeError, ValueError, AssertionError) as e:
common.error(self, "Couldn't parse body as JSON: %s" % e)
type = activity.get('type')
if type not in SUPPORTED_TYPES:
common.error(self, 'Sorry, %s activities are not supported yet.' % type,
status=501)
# TODO: verify signature if there is one

Wyświetl plik

@ -19,6 +19,15 @@ import common
ATOM_NS = 'http://www.w3.org/2005/Atom'
ATOM_THREADING_NS = 'http://purl.org/syndication/thread/1.0'
SUPPORTED_VERBS = (
'checkin',
'create',
'like',
'share',
'tag',
'update',
)
class SlapHandler(webapp2.RequestHandler):
"""Accepts POSTs to /[ACCT]/salmon and converts to outbound webmentions."""
@ -34,8 +43,19 @@ class SlapHandler(webapp2.RequestHandler):
data = utils.decode(parsed['data'])
logging.info('Decoded: %s', data)
# verify signature
author = utils.parse_author_uri_from_atom(data)
# check that we support this activity type
try:
activity = atom.atom_to_activity(data)
except ParseError as e:
common.error(self, 'Could not parse envelope data as XML: %s' % e)
verb = activity.get('verb')
if verb and verb not in SUPPORTED_VERBS:
common.error(self, 'Sorry, %s activities are not supported yet.' % type,
status=501)
# verify author and signature
author = util.get_url(activity.get('actor'))
if ':' not in author:
author = 'acct:%s' % author
elif not author.startswith('acct:'):

Wyświetl plik

@ -154,3 +154,13 @@ class ActivityPubTest(testutil.TestCase):
self.assertEqual('complete', resp.status)
as2_like['actor'] = actor
self.assertEqual(as2_like, json.loads(resp.source_as2))
def test_inbox_unsupported_type(self, mock_get, mock_post):
got = app.get_response('/foo.com/inbox', method='POST', body=json.dumps({
'@context': ['https://www.w3.org/ns/activitystreams'],
'id': 'https://xoxo.zone/users/aaronpk#follows/40',
'type': 'Follow',
'actor': 'https://xoxo.zone/users/aaronpk',
'object': 'http://snarfed.org/',
}))
self.assertEquals(501, got.status_int)

Wyświetl plik

@ -24,9 +24,12 @@ import testutil
@mock.patch('urllib2.urlopen')
class SalmonTest(testutil.TestCase):
def setUp(self):
super(SalmonTest, self).setUp()
self.key = MagicKey.get_or_create('alice')
def send_slap(self, mock_urlopen, mock_get, mock_post, atom_slap):
# salmon magic key discovery. first host-meta, then webfinger
self.key = MagicKey.get_or_create('alice')
mock_urlopen.side_effect = [
UrlopenResult(200, """\
<?xml version='1.0' encoding='UTF-8'?>
@ -131,7 +134,24 @@ class SalmonTest(testutil.TestCase):
self.assertEqual('complete', resp.status)
self.assertEqual(atom_like, resp.source_atom)
def test_bad_xml(self, mock_urlopen, mock_get, mock_post):
def test_bad_envelope(self, mock_urlopen, mock_get, mock_post):
got = app.get_response('/foo.com/salmon', method='POST',
body='not xml'.encode('utf-8'))
self.assertEquals(400, got.status_int)
def test_bad_inner_xml(self, mock_urlopen, mock_get, mock_post):
slap = magicsigs.magic_envelope('not xml', common.ATOM_CONTENT_TYPE, self.key)
got = app.get_response('/foo.com/salmon', method='POST', body=slap)
self.assertEquals(400, got.status_int)
def test_rsvp_not_supported(self, mock_urlopen, mock_get, mock_post):
slap = magicsigs.magic_envelope("""\
<?xml version='1.0' encoding='UTF-8'?>
<entry xmlns='http://www.w3.org/2005/Atom'
xmlns:activity='http://activitystrea.ms/spec/1.0/'>
<uri>https://my/rsvp</uri>
<activity:verb>http://activitystrea.ms/schema/1.0/rsvp</activity:verb>
<activity:object>http://orig/event</activity:object>
</entry>""", common.ATOM_CONTENT_TYPE, self.key)
got = app.get_response('/foo.com/salmon', method='POST', body=slap)
self.assertEquals(501, got.status_int)