diff --git a/bookwyrm/outgoing.py b/bookwyrm/outgoing.py index 68d790133..95b89d9f9 100644 --- a/bookwyrm/outgoing.py +++ b/bookwyrm/outgoing.py @@ -15,6 +15,7 @@ from bookwyrm.status import create_generated_note from bookwyrm.status import delete_status from bookwyrm.remote_user import get_or_create_remote_user from bookwyrm.settings import DOMAIN +from bookwyrm.utils import regex @csrf_exempt @@ -36,13 +37,17 @@ def outbox(request, username): def handle_remote_webfinger(query): - ''' webfingerin' other servers ''' + ''' webfingerin' other servers, username query should be user@domain ''' user = None - domain = query.split('@')[1] + try: + domain = query.split('@')[2] + except IndexError: + return None + try: user = models.User.objects.get(username=query) except models.User.DoesNotExist: - url = 'https://%s/.well-known/webfinger?resource=acct:%s' % \ + url = 'https://%s/.well-known/webfinger?resource=acct:@%s' % \ (domain, query) try: response = requests.get(url) @@ -57,7 +62,7 @@ def handle_remote_webfinger(query): user = get_or_create_remote_user(link['href']) except KeyError: return None - return [user] + return user def handle_follow(user, to_follow): @@ -216,7 +221,7 @@ def handle_status(user, form): # inspect the text for user tags text = status.content matches = re.finditer( - r'\W@[a-zA-Z_\-\.0-9]+(@[a-z-A-Z0-9_\-]+.[a-z]+)?', + regex.username, text ) for match in matches: @@ -226,9 +231,8 @@ def handle_status(user, form): username.append(DOMAIN) username = '@'.join(username) - try: - mention_user = models.User.objects.get(username=username) - except models.User.DoesNotExist: + mention_user = handle_remote_webfinger(username) + if not mention_user: # we can ignore users we don't know about continue # add them to status mentions fk diff --git a/bookwyrm/utils/__init__.py b/bookwyrm/utils/__init__.py index e69de29bb..a90554c70 100644 --- a/bookwyrm/utils/__init__.py +++ b/bookwyrm/utils/__init__.py @@ -0,0 +1 @@ +from .regex import username diff --git a/bookwyrm/views.py b/bookwyrm/views.py index 4721644c8..4666409da 100644 --- a/bookwyrm/views.py +++ b/bookwyrm/views.py @@ -16,6 +16,7 @@ from bookwyrm.activitypub import ActivityEncoder from bookwyrm import forms, models, books_manager from bookwyrm import goodreads_import from bookwyrm.tasks import app +from bookwyrm.utils import regex def get_user_from_username(username): @@ -168,7 +169,7 @@ def search(request): return JsonResponse([r.__dict__ for r in book_results], safe=False) # use webfinger looks like a mastodon style account@domain.com username - if re.match(r'\w+@\w+.\w+', query): + if re.match(regex.full_username, query): outgoing.handle_remote_webfinger(query) # do a local user search diff --git a/bookwyrm/wellknown.py b/bookwyrm/wellknown.py index b59256fcb..94320c2de 100644 --- a/bookwyrm/wellknown.py +++ b/bookwyrm/wellknown.py @@ -1,5 +1,5 @@ ''' responds to various requests to /.well-know ''' -from django.http import HttpResponseBadRequest, HttpResponseNotFound +from django.http import HttpResponseNotFound from django.http import JsonResponse from bookwyrm import models @@ -13,11 +13,14 @@ def webfinger(request): resource = request.GET.get('resource') if not resource and not resource.startswith('acct:'): - return HttpResponseBadRequest() - ap_id = resource.replace('acct:', '') - user = models.User.objects.filter(username=ap_id).first() - if not user: + return HttpResponseNotFound() + + username = resource.replace('acct:@', '') + try: + user = models.User.objects.get(username=username) + except models.User.DoesNotExist: return HttpResponseNotFound('No account found') + return JsonResponse({ 'subject': 'acct:%s' % (user.username), 'links': [