Add WebFinger support and refactor some of the request manip stuff

This commit is contained in:
Danielle McLean 2017-10-27 13:24:57 +11:00
parent 00d7a29b2d
commit 1a9582213a
Signed by untrusted user: 00dani
GPG key ID: 5A5D2D1AFF12EEC5
7 changed files with 81 additions and 22 deletions

View file

@ -1,7 +1,6 @@
from django.shortcuts import get_object_or_404, render from django.shortcuts import get_object_or_404, render
from users.models import User from users.models import User
from lemoncurry import breadcrumbs from lemoncurry import breadcrumbs, utils
from lemoncurry.templatetags.lemoncurry_tags import request_uri
breadcrumbs.add('home:index', 'home') breadcrumbs.add('home:index', 'home')
@ -9,7 +8,7 @@ breadcrumbs.add('home:index', 'home')
def index(request): def index(request):
query = User.objects.prefetch_related('entries', 'profiles', 'keys') query = User.objects.prefetch_related('entries', 'profiles', 'keys')
user = get_object_or_404(query, pk=1) user = get_object_or_404(query, pk=1)
uri = request_uri(request) uri = utils.uri(request)
person = { person = {
'@context': 'http://schema.org', '@context': 'http://schema.org',
'@type': 'Person', '@type': 'Person',

View file

@ -1,16 +1,13 @@
import json
from os.path import join
from types import SimpleNamespace
from django import template from django import template
from django.conf import settings from django.conf import settings
from django.urls import reverse from django.urls import reverse
from ..utils import load_package_json, origin, uri
from .. import breadcrumbs from .. import breadcrumbs
from entries import kinds from entries import kinds
register = template.Library() register = template.Library()
cache = SimpleNamespace(package_json=None)
class MenuItem: class MenuItem:
@ -22,24 +19,17 @@ class MenuItem:
@register.simple_tag @register.simple_tag
def get_package_json(): def get_package_json():
if cache.package_json: return load_package_json()
return cache.package_json
with open(join(settings.BASE_DIR, 'package.json')) as f:
cache.package_json = json.load(f)
return cache.package_json
@register.simple_tag @register.simple_tag
def request_origin(request): def request_origin(request):
return '{scheme}://{host}'.format( return origin(request)
scheme=request.scheme,
host=request.META['HTTP_HOST'],
)
@register.simple_tag @register.simple_tag
def request_uri(request): def request_uri(request):
return request_origin(request) + request.path return uri(request)
@register.simple_tag @register.simple_tag

22
lemoncurry/utils.py Normal file
View file

@ -0,0 +1,22 @@
import json
from django.conf import settings
from os.path import join
from types import SimpleNamespace
cache = SimpleNamespace(package_json=None)
def load_package_json():
if cache.package_json:
return cache.package_json
with open(join(settings.BASE_DIR, 'package.json')) as f:
cache.package_json = json.load(f)
return cache.package_json
def origin(request):
return '{0}://{1}'.format(request.scheme, request.META['HTTP_HOST'])
def uri(request):
return origin(request) + request.path

View file

@ -7,4 +7,5 @@ urlpatterns = [
url(r'^keybase.txt$', views.keybase, name='keybase'), url(r'^keybase.txt$', views.keybase, name='keybase'),
url(r'^host-meta$', views.host_meta_xml, name='host-meta'), url(r'^host-meta$', views.host_meta_xml, name='host-meta'),
url(r'^host-meta.json$', views.host_meta_json, name='host-meta.json'), url(r'^host-meta.json$', views.host_meta_json, name='host-meta.json'),
url(r'^webfinger$', views.webfinger, name='webfinger'),
] ]

View file

@ -1,2 +1,3 @@
from .static import keybase from .static import keybase
from .host_meta import host_meta_xml, host_meta_json from .host_meta import host_meta_xml, host_meta_json
from .webfinger import webfinger

View file

@ -1,12 +1,15 @@
from django.http import HttpResponse from django.http import HttpResponse
from django.conf import settings from django.urls import reverse
from lemoncurry.templatetags.lemoncurry_tags import get_package_json from lemoncurry.utils import load_package_json, origin
from urllib.parse import urljoin
from xrd import XRD, Attribute, Element, Link from xrd import XRD, Attribute, Element, Link
def add_links(dest): def add_links(request, dest):
package = get_package_json() base = origin(request)
package = load_package_json()
links = ( links = (
Link(rel='lrdd', template=urljoin(base, reverse('wellknowns:webfinger') + '?resource={uri}')),
Link(rel='license', href='https://creativecommons.org/licenses/by-sa/4.0/'), Link(rel='license', href='https://creativecommons.org/licenses/by-sa/4.0/'),
Link(rel='code-repository', href=package['repository']), Link(rel='code-repository', href=package['repository']),
) )
@ -17,7 +20,7 @@ def host_meta(request):
h = XRD() h = XRD()
h.attributes.append(Attribute('xmlns:hm', 'http://host-meta.net/ns/1.0')) h.attributes.append(Attribute('xmlns:hm', 'http://host-meta.net/ns/1.0'))
h.elements.append(Element('hm:Host', request.META['HTTP_HOST'])) h.elements.append(Element('hm:Host', request.META['HTTP_HOST']))
add_links(h.links) add_links(request, h.links)
return h return h

View file

@ -0,0 +1,43 @@
from django.http import HttpResponseBadRequest, HttpResponseNotFound
from django.http import JsonResponse
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'
def webfinger(request):
if 'resource' not in request.GET:
return HttpResponseBadRequest('resource parameter missing')
try:
resource = urlparse(request.GET['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')
base = origin(request)
def link(rel, href, type):
return {'rel': rel, 'href': urljoin(base, href), 'type': type}
info = {
'subject': 'acct:' + user.email,
'aliases': (
urljoin(base, user.url),
'mailto:' + user.email,
),
'links': (
link(rel=AVATAR, href=user.avatar.url, type='image/png'),
link(rel=PROFILE_PAGE, href=user.url, type='text/html'),
),
}
return JsonResponse(info, content_type='application/jrd+json')