Skip to content
Snippets Groups Projects
Verified Commit cb55f756 authored by Eliot Berriot's avatar Eliot Berriot
Browse files

Basic logic to extract provider data from URLs

parent 75f93916
No related branches found
No related tags found
No related merge requests found
import re
class Registry(object):
def __init__(self):
self._data = {}
def register(self, obj):
if not obj.id:
raise ValueError("{} has no id".format(obj.id))
self._data[obj.id] = obj()
def __iter__(self):
yield from self._data.items()
registry = Registry()
class Provider(object):
id = None
domains = []
username_regex = None
class BasicUsernameProvider(Provider):
username_regex = r"^\/([\w\.]+)/?$"
def match_from_url(self, parsed_url):
if not self.domains and not self.username_regex:
return
if parsed_url.hostname not in self.domains:
return
compiled = re.compile(self.username_regex)
result = compiled.match(parsed_url.path)
if not result:
return
username = result.groups()[0]
return {"provider": self.id, "id": username}
@registry.register
class Patreon(BasicUsernameProvider):
id = "patreon"
domains = ["patreon.com"]
@registry.register
class Liberapay(BasicUsernameProvider):
id = "liberapay"
domains = ["liberapay.com"]
@registry.register
class KoFi(BasicUsernameProvider):
id = "ko-fi"
domains = ["ko-fi.com"]
import urllib.parse
from retribute_api import providers
def extract_from_url(url):
parsed = urllib.parse.urlparse(url)
for id, provider in providers.registry:
result = provider.match_from_url(parsed)
if result:
return result
return None
from rest_framework import serializers
async def lookup(name, session):
username, domain = name.split("@")
response = await session.get(
"https://{}/.well-known/webfinger".format(domain),
params={"resource": "acct:{}".format(name)},
)
response.raise_for_status()
return await response.json()
class AccountLinkSerializer(serializers.Serializer):
rel = serializers.CharField()
href = serializers.URLField()
type = serializers.CharField()
class WebfingerSerializer(serializers.Serializer):
links = serializers.ListField(child=AccountLinkSerializer(), min_length=1)
def get_links(payload):
serializer = WebfingerSerializer(data=payload)
serializer.is_valid(raise_exception=True)
links = {}
for link in serializer.validated_data["links"]:
if link["rel"] != "self":
continue
if link["type"] == "application/activity+json":
links["activitypub"] = link["href"]
return links
......@@ -65,6 +65,7 @@ universal = 1
[tool:pytest]
testpaths = tests
env =
DJANGO_SETTINGS_MODULE=config.settings.base
SECRET_KEY=test
EMAIL_CONFIG=consolemail://
DEBUG_TOOLBAR_ENABLED=False
......
import pytest
import aiohttp
from aioresponses import aioresponses
import asynctest
pytest_plugins = "aiohttp.pytest_plugin"
@pytest.fixture
def responses():
with aioresponses() as m:
yield m
@pytest.fixture
async def session(loop):
async with aiohttp.ClientSession() as session:
yield session
@pytest.fixture
async def coroutine_mock():
return asynctest.CoroutineMock
import pytest
from retribute_api.search import means
@pytest.mark.parametrize(
"input, expected",
[
("https://patreon.com/username", {"provider": "patreon", "id": "username"}),
("https://liberapay.com/username", {"provider": "liberapay", "id": "username"}),
("https://ko-fi.com/username", {"provider": "ko-fi", "id": "username"}),
("https://patreon.com/username/nope", None),
],
)
def test_extract_from_url(input, expected):
assert means.extract_from_url(input) == expected
from retribute_api.search import webfinger
async def test_wellknown_success(responses, session):
name = "user@domain.test"
webfinger_response = {
"subject": "acct:user@domain.test",
"aliases": ["https://domain.test/@user", "https://domain.test/users/user"],
"links": [
{
"rel": "self",
"type": "application/activity+json",
"href": "https://domain.test/users/user",
}
],
}
responses.get(
"https://domain.test/.well-known/webfinger?resource=acct:{}".format(name),
payload=webfinger_response,
)
response = await webfinger.lookup(name, session)
assert response == webfinger_response
def test_get_links(settings):
payload = {
"links": [
{
"rel": "self",
"type": "application/activity+json",
"href": "https://domain.test/users/user",
}
]
}
expected = {"activitypub": "https://domain.test/users/user"}
assert webfinger.get_links(payload) == expected
def test_something():
assert 1 == 2
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment