kopia lustrzana https://github.com/snarfed/bridgy-fed
rodzic
5485cbeece
commit
c54df36164
2
app.py
2
app.py
|
@ -6,7 +6,7 @@ registered.
|
||||||
from flask_app import app
|
from flask_app import app
|
||||||
|
|
||||||
# import all modules to register their Flask handlers
|
# import all modules to register their Flask handlers
|
||||||
import activitypub, atproto, convert, follow, pages, redirect, superfeedr, ui, webfinger, web
|
import activitypub, atproto, convert, follow, pages, redirect, ui, webfinger, web
|
||||||
|
|
||||||
import models
|
import models
|
||||||
models.reset_protocol_properties()
|
models.reset_protocol_properties()
|
||||||
|
|
|
@ -55,11 +55,6 @@ render
|
||||||
.. automodule:: render
|
.. automodule:: render
|
||||||
:exclude-members: __eq__, __getnewargs__, __getstate__, __hash__, __new__, __repr__, __str__, __weakref__
|
:exclude-members: __eq__, __getnewargs__, __getstate__, __hash__, __new__, __repr__, __str__, __weakref__
|
||||||
|
|
||||||
superfeedr
|
|
||||||
----------
|
|
||||||
.. automodule:: superfeedr
|
|
||||||
:exclude-members: __eq__, __getnewargs__, __getstate__, __hash__, __new__, __repr__, __str__, __weakref__
|
|
||||||
|
|
||||||
web
|
web
|
||||||
---
|
---
|
||||||
.. automodule:: web
|
.. automodule:: web
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
"""Superfeedr callback handlers.
|
|
||||||
|
|
||||||
Not really sure what this will be yet.
|
|
||||||
|
|
||||||
* https://github.com/snarfed/bridgy-fed/issues/550
|
|
||||||
* https://github.com/snarfed/bridgy-fed/issues/18#issuecomment-430731476
|
|
||||||
* https://documentation.superfeedr.com/publishers.html
|
|
||||||
"""
|
|
||||||
import logging
|
|
||||||
|
|
||||||
from flask import request
|
|
||||||
|
|
||||||
from flask_app import app
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
@app.route(r'/superfeedr/', methods=['GET', 'POST'])
|
|
||||||
@app.route(r'/superfeedr/<path:_>', methods=['GET', 'POST'])
|
|
||||||
def superfeedr(_=None):
|
|
||||||
"""Superfeedr subscription callback handler.
|
|
||||||
|
|
||||||
https://documentation.superfeedr.com/publishers.html#subscription-callback
|
|
||||||
"""
|
|
||||||
logger.info(f'Got:\n{request.get_data(as_text=True)}')
|
|
||||||
return '', 204
|
|
|
@ -4,7 +4,7 @@ from unittest.mock import patch
|
||||||
|
|
||||||
from flask import g, get_flashed_messages
|
from flask import g, get_flashed_messages
|
||||||
from google.cloud import ndb
|
from google.cloud import ndb
|
||||||
from granary import as1, as2, microformats2
|
from granary import as1, as2, atom, microformats2
|
||||||
from oauth_dropins.webutil import util
|
from oauth_dropins.webutil import util
|
||||||
from oauth_dropins.webutil import appengine_info
|
from oauth_dropins.webutil import appengine_info
|
||||||
from oauth_dropins.webutil.testutil import NOW, requests_response
|
from oauth_dropins.webutil.testutil import NOW, requests_response
|
||||||
|
@ -1735,6 +1735,38 @@ class WebTest(TestCase):
|
||||||
"WARNING:models:actor https://user.com/ isn't https://user.com/like's author or actor ['https://eve.com/']",
|
"WARNING:models:actor https://user.com/ isn't https://user.com/like's author or actor ['https://eve.com/']",
|
||||||
logs.output)
|
logs.output)
|
||||||
|
|
||||||
|
@patch('oauth_dropins.webutil.appengine_config.tasks_client.create_task')
|
||||||
|
def test_superfeedr_make_task(self, mock_create_task, *_):
|
||||||
|
common.RUN_TASKS_INLINE = False
|
||||||
|
|
||||||
|
got = self.post('/superfeedr/notify/user.com', data="""\
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<entry xmlns="http://www.w3.org/2005/Atom">
|
||||||
|
<uri>https://user.com/post</uri>
|
||||||
|
<content>I hereby ☕ post.</content>
|
||||||
|
</entry>
|
||||||
|
""", headers={'Content-Type': atom.CONTENT_TYPE})
|
||||||
|
self.assertEqual(200, got.status_code)
|
||||||
|
self.assert_task(mock_create_task, 'receive', '/queue/receive',
|
||||||
|
obj=Object(id='https://user.com/post').key.urlsafe(),
|
||||||
|
authed_as='user.com')
|
||||||
|
|
||||||
|
def test_superfeedr_no_user(self, *_):
|
||||||
|
orig_count = Object.query().count()
|
||||||
|
|
||||||
|
got = self.post('/webmention', data={'source': 'https://nope.com/post'})
|
||||||
|
self.assertEqual(400, got.status_code)
|
||||||
|
self.assertEqual(orig_count, Object.query().count())
|
||||||
|
|
||||||
|
def test_superfeedr_no_id(self, *mocks):
|
||||||
|
got = self.post('/superfeedr/notify/user.com', data="""\
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<entry xmlns="http://www.w3.org/2005/Atom">
|
||||||
|
<content>I hereby ☕ post.</content>
|
||||||
|
</entry>
|
||||||
|
""", headers={'Content-Type': atom.CONTENT_TYPE})
|
||||||
|
self.assertEqual(400, got.status_code)
|
||||||
|
|
||||||
def _test_verify(self, redirects, hcard, actor, redirects_error=None):
|
def _test_verify(self, redirects, hcard, actor, redirects_error=None):
|
||||||
self.user.has_redirects = False
|
self.user.has_redirects = False
|
||||||
self.user.put()
|
self.user.put()
|
||||||
|
|
36
web.py
36
web.py
|
@ -9,7 +9,7 @@ from urllib.parse import quote, urlencode, urljoin, urlparse
|
||||||
from flask import g, redirect, render_template, request
|
from flask import g, redirect, render_template, request
|
||||||
from google.cloud import ndb
|
from google.cloud import ndb
|
||||||
from google.cloud.ndb import ComputedProperty
|
from google.cloud.ndb import ComputedProperty
|
||||||
from granary import as1, as2, microformats2
|
from granary import as1, as2, atom, microformats2
|
||||||
import mf2util
|
import mf2util
|
||||||
from oauth_dropins.webutil import flask_util, util
|
from oauth_dropins.webutil import flask_util, util
|
||||||
from oauth_dropins.webutil.appengine_config import tasks_client
|
from oauth_dropins.webutil.appengine_config import tasks_client
|
||||||
|
@ -581,6 +581,38 @@ def webmention_interactive():
|
||||||
return redirect('/', code=302)
|
return redirect('/', code=302)
|
||||||
|
|
||||||
|
|
||||||
|
# generate/check per-user token for auth?
|
||||||
|
# or https://documentation.superfeedr.com/subscribers.html#http-authentication ?
|
||||||
|
@app.post(f'/superfeedr/notify/<regex("{DOMAIN_RE}"):domain>')
|
||||||
|
def superfeedr_notify(domain):
|
||||||
|
"""Superfeedr notification handler.
|
||||||
|
|
||||||
|
https://documentation.superfeedr.com/publishers.html#subscription-callback
|
||||||
|
"""
|
||||||
|
logger.info(f'Got:\n{request.get_data(as_text=True)}')
|
||||||
|
|
||||||
|
type = request.headers.get('Content-Type', '').split(';')[0]
|
||||||
|
if type != atom.CONTENT_TYPE.split(';')[0]:
|
||||||
|
error(f'Expected Content-Type {atom.CONTENT_TYPE}, got {type}', status=406)
|
||||||
|
|
||||||
|
user = Web.get_by_id(domain)
|
||||||
|
if not user:
|
||||||
|
error(f'No user found for domain {domain}', status=304)
|
||||||
|
|
||||||
|
text = request.get_data(as_text=True)
|
||||||
|
obj = Object(atom=text)
|
||||||
|
logger.info(f'Converted to AS1: {json_dumps(obj.as1, indent=2)}')
|
||||||
|
|
||||||
|
id = obj.as1.get('id')
|
||||||
|
if not id:
|
||||||
|
return error('No id or URL!')
|
||||||
|
|
||||||
|
obj = Object.get_or_create(id=id, atom=text, source_protocol=Web.ABBREV)
|
||||||
|
common.create_task(queue='receive', obj=obj.key.urlsafe(), authed_as=domain)
|
||||||
|
|
||||||
|
return 'OK'
|
||||||
|
|
||||||
|
|
||||||
@app.post('/queue/webmention')
|
@app.post('/queue/webmention')
|
||||||
@cloud_tasks_only
|
@cloud_tasks_only
|
||||||
def webmention_task():
|
def webmention_task():
|
||||||
|
@ -593,9 +625,9 @@ def webmention_task():
|
||||||
logger.info(f'webmention from {domain}')
|
logger.info(f'webmention from {domain}')
|
||||||
|
|
||||||
user = Web.get_by_id(domain)
|
user = Web.get_by_id(domain)
|
||||||
logger.info(f'User: {user.key}')
|
|
||||||
if not user:
|
if not user:
|
||||||
error(f'No user found for domain {domain}', status=304)
|
error(f'No user found for domain {domain}', status=304)
|
||||||
|
logger.info(f'User: {user.key}')
|
||||||
|
|
||||||
# fetch source page
|
# fetch source page
|
||||||
try:
|
try:
|
||||||
|
|
Ładowanie…
Reference in New Issue