Web: start on Superfeedr subscribe

for #550
pull/746/head
Ryan Barrett 2023-12-04 10:28:45 -08:00
rodzic 68ba590ae2
commit b113521f94
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 6BE31FDF4776E9D4
3 zmienionych plików z 46 dodań i 2 usunięć

2
.gitignore vendored
Wyświetl plik

@ -10,4 +10,6 @@ flask_secret_key
opt_outs.txt
private_notes
service_account_creds.json
superfeedr_token
superfeedr_username
TAGS

Wyświetl plik

@ -1,6 +1,6 @@
"""Unit tests for webmention.py."""
import copy
from unittest.mock import patch
from unittest.mock import ANY, patch
from flask import g, get_flashed_messages
from google.cloud import ndb
@ -20,7 +20,8 @@ import common
from common import CONTENT_TYPE_HTML
from flask_app import app
from models import Follower, Object
from web import TASKS_LOCATION, Web
import web
from web import SUPERFEEDR_PUSH_API, TASKS_LOCATION, Web
from . import test_activitypub
from .testutil import Fake, TestCase
@ -1769,6 +1770,17 @@ class WebTest(TestCase):
""", headers={'Content-Type': atom.CONTENT_TYPE})
self.assertEqual(400, got.status_code)
@patch('oauth_dropins.webutil.appengine_info.LOCAL_SERVER', False)
def test_superfeedr_subscribe(self, mock_get, mock_post):
web.superfeedr_subscribe(self.user)
self.assert_req(mock_post, SUPERFEEDR_PUSH_API, data={
'hub.mode': 'subscribe',
'hub.topic': 'https://user.com/feed',
'hub.callback': 'http://localhost/superfeedr/notify/user.com',
'format': 'atom',
'retrieve': 'true',
}, auth=ANY)
def _test_verify(self, redirects, hcard, actor, redirects_error=None):
self.user.has_redirects = False
self.user.put()

30
web.py
Wyświetl plik

@ -18,6 +18,7 @@ from oauth_dropins.webutil.flask_util import cloud_tasks_only, error, flash
from oauth_dropins.webutil.util import json_dumps, json_loads
from oauth_dropins.webutil import webmention
from requests import HTTPError, RequestException
from requests.auth import HTTPBasicAuth
from werkzeug.exceptions import BadGateway, BadRequest, HTTPException, NotFound
import common
@ -54,6 +55,10 @@ NON_TLDS = frozenset((
'yml',
))
SUPERFEEDR_PUSH_API = 'https://push.superfeedr.com'
SUPERFEEDR_USERNAME = util.read('superfeedr_username')
SUPERFEEDR_TOKEN = util.read('superfeedr_token')
def is_valid_domain(domain):
"""Returns True if this is a valid domain we can use, False otherwise.
@ -586,6 +591,31 @@ def webmention_interactive():
return redirect('/', code=302)
def superfeedr_subscribe(user):
"""Subscribes to a user's Atom or RSS feed in Superfeedr.
Args:
user (Web)
"""
logger.info(f'Subscribing to {user.key.id()} via Superfeedr')
if appengine_info.LOCAL_SERVER:
logger.info(f"Skipping since we're local")
return
auth = HTTPBasicAuth(SUPERFEEDR_USERNAME, SUPERFEEDR_TOKEN)
resp = util.requests_post(SUPERFEEDR_PUSH_API, auth=auth, data={
'hub.mode': 'subscribe',
'hub.topic': f'{user.web_url()}feed',
'hub.callback': common.host_url(f'/superfeedr/notify/{user.key.id()}'),
# TODO
# 'hub.secret': 'xxx',
'format': 'atom',
'retrieve': 'true',
})
resp.raise_for_status()
return resp
# 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>')