kopia lustrzana https://github.com/snarfed/bridgy-fed
activitypub and salmon: return 501 on unsupported activity type
rodzic
02f1e67cf9
commit
bf0897ba81
|
@ -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
|
||||
|
||||
|
|
24
salmon.py
24
salmon.py
|
@ -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:'):
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
Ładowanie…
Reference in New Issue