Replace the previous WebFinger implementation with a fairly simple forwarder to Bridgy Fed, so that Bridgy Fed will work eventually
This commit is contained in:
parent
9f3cbac3c4
commit
46c2224a4f
2 changed files with 50 additions and 37 deletions
|
@ -84,7 +84,11 @@ class User(ModelMeta, AbstractUser):
|
|||
return '{0} {1}'.format(self.first_name, self.last_name)
|
||||
|
||||
def get_absolute_url(self):
|
||||
return self.url
|
||||
return self.absolute_url
|
||||
|
||||
@property
|
||||
def absolute_url(self):
|
||||
return self.full_url
|
||||
|
||||
@property
|
||||
def full_url(self):
|
||||
|
|
|
@ -1,50 +1,59 @@
|
|||
from django.http import HttpResponseBadRequest, HttpResponseNotFound
|
||||
from django.http import JsonResponse
|
||||
from django.http import HttpResponseBadRequest, HttpResponseRedirect
|
||||
from urllib.parse import urlencode, urlparse
|
||||
|
||||
from users.models import User
|
||||
from django.shortcuts import get_object_or_404
|
||||
from urllib.parse import urlparse, urljoin
|
||||
from lemoncurry.utils import origin
|
||||
|
||||
AVATAR = 'http://webfinger.net/rel/avatar'
|
||||
PROFILE_PAGE = 'http://webfinger.net/rel/profile-page'
|
||||
BRIDGY_FED = 'https://fed.brid.gy/.well-known/webfinger'
|
||||
|
||||
|
||||
def https_resource_matching(resource):
|
||||
"""
|
||||
Takes a `urllib.parse.urlparse` tuple representing a WebFinger resource and
|
||||
translates ``mailto:`` and ``xmpp:`` resources to an equivalent ``https:``
|
||||
resource, if a user with matching email or XMPP address exists locally.
|
||||
Will throw `User.DoesNotExist` if no such user exists.
|
||||
"""
|
||||
if resource.scheme == 'mailto':
|
||||
query = {'email': resource.path}
|
||||
else:
|
||||
query = {'xmpp': resource.path}
|
||||
return User.objects.get(**query).absolute_url
|
||||
|
||||
|
||||
def webfinger(request):
|
||||
"""
|
||||
A thin wrapper around Bridgy Fed's implementation of WebFinger.
|
||||
|
||||
In most cases, this view simply redirects to the same endpoint at Bridgy.
|
||||
However, Bridgy does not support the ``mailto:`` and ``xmpp:`` resource
|
||||
schemes - quite reasonably, since there's no possible way to discover the
|
||||
``acct:`` they go with! - so resources with those schemes are translated
|
||||
locally into an ``https:`` URL representing the same person, and *then*
|
||||
redirected to Bridgy.
|
||||
|
||||
Additionally, WebFinger requests with a missing or malformed resource will
|
||||
be rejected immediately rather than passed on to Bridgy.
|
||||
|
||||
Note that the translation step will only be applied if there exists a
|
||||
:model:`users.User` with matching email or XMPP address. Otherwise, the
|
||||
original resource will be preserved in the redirect - and likely fail to
|
||||
find anything at Bridgy's end either.
|
||||
"""
|
||||
if 'resource' not in request.GET:
|
||||
return HttpResponseBadRequest('resource parameter missing')
|
||||
resource = request.GET['resource']
|
||||
try:
|
||||
resource = urlparse(request.GET['resource'])
|
||||
res = urlparse(resource)
|
||||
except ValueError:
|
||||
return HttpResponseBadRequest('resource parameter malformed')
|
||||
|
||||
if resource.scheme in ('mailto', 'acct', 'xmpp'):
|
||||
user = get_object_or_404(User, email=resource.path)
|
||||
elif resource.scheme in ('http', 'https'):
|
||||
user = get_object_or_404(User, pk=1)
|
||||
else:
|
||||
return HttpResponseNotFound('resource not found on this server')
|
||||
if res.scheme in ('mailto', 'xmpp'):
|
||||
try:
|
||||
resource = https_resource_matching(res)
|
||||
except User.DoesNotExist:
|
||||
pass
|
||||
|
||||
base = origin(request)
|
||||
|
||||
def link(rel, href, type):
|
||||
return {'rel': rel, 'href': urljoin(base, href), 'type': type}
|
||||
|
||||
key_links = tuple(link(
|
||||
rel='pgpkey',
|
||||
href=key.file.url,
|
||||
type='application/pgp-keys',
|
||||
) for key in user.keys.all())
|
||||
|
||||
info = {
|
||||
'subject': 'acct:' + user.email,
|
||||
'aliases': (
|
||||
urljoin(base, user.url),
|
||||
'mailto:' + user.email,
|
||||
'xmpp:' + user.xmpp,
|
||||
),
|
||||
'links': (
|
||||
link(rel=AVATAR, href=user.avatar.url, type='image/png'),
|
||||
link(rel=PROFILE_PAGE, href=user.url, type='text/html'),
|
||||
) + key_links,
|
||||
}
|
||||
return JsonResponse(info, content_type='application/jrd+json')
|
||||
query = urlencode({'resource': resource})
|
||||
return HttpResponseRedirect(BRIDGY_FED + '?' + query)
|
||||
|
|
Loading…
Reference in a new issue