From 221d548e4a205a9dac8a3b957edb0e39d6b8cd69 Mon Sep 17 00:00:00 2001 From: Danielle McLean Date: Sun, 29 Oct 2017 14:39:30 +1100 Subject: [PATCH] Give better 'me' normalisation to IndieAuth processing + Aadd a simple POST route for actually submitting the form --- lemonauth/templates/lemonauth/indie.html | 12 ++++--- lemonauth/urls.py | 1 + lemonauth/views/__init__.py | 2 +- lemonauth/views/indie.py | 44 ++++++++++++++++-------- 4 files changed, 38 insertions(+), 21 deletions(-) diff --git a/lemonauth/templates/lemonauth/indie.html b/lemonauth/templates/lemonauth/indie.html index 5746b7d..1f03a0a 100644 --- a/lemonauth/templates/lemonauth/indie.html +++ b/lemonauth/templates/lemonauth/indie.html @@ -7,7 +7,7 @@ {% block main %}
-
+

{% if app %}{% endif %} sign in to @@ -16,7 +16,7 @@

-

do you want to confirm your identity, {{ params.me }}, with this app?

+

do you want to confirm your identity, {{ me }}, with this app?

you will be redirected to {{ params.redirect_uri }} after authorising this app

@@ -28,9 +28,11 @@
{% csrf_token %} - {% if params.state %} - - {% endif %} + + + + {% if params.state %}{% endif %} + {% endblock %} diff --git a/lemonauth/urls.py b/lemonauth/urls.py index 4107cf2..0e3aec9 100644 --- a/lemonauth/urls.py +++ b/lemonauth/urls.py @@ -6,4 +6,5 @@ urlpatterns = [ url('^login$', views.login, name='login'), url('^logout$', views.logout, name='logout'), url('^indie$', views.IndieView.as_view(), name='indie'), + url('^indie/approve$', views.indie_approve, name='indie_approve'), ] diff --git a/lemonauth/views/__init__.py b/lemonauth/views/__init__.py index c53d50a..3a2e4c3 100644 --- a/lemonauth/views/__init__.py +++ b/lemonauth/views/__init__.py @@ -1,3 +1,3 @@ from .login import login from .logout import logout -from .indie import IndieView +from .indie import IndieView, approve as indie_approve diff --git a/lemonauth/views/indie.py b/lemonauth/views/indie.py index e7a7e5d..a7d584c 100644 --- a/lemonauth/views/indie.py +++ b/lemonauth/views/indie.py @@ -1,23 +1,39 @@ import mf2py +from annoying.decorators import render_to from django.contrib.auth.decorators import login_required from django.http import HttpResponseForbidden, HttpResponseBadRequest -from django.shortcuts import render +from django.http import JsonResponse from django.utils.decorators import method_decorator from django.views.generic import TemplateView +from django.views.decorators.http import require_POST from lemoncurry import breadcrumbs, utils -from urllib.parse import urljoin +from urllib.parse import urljoin, urlunparse, urlparse breadcrumbs.add('lemonauth:indie', label='indieauth', parent='home:index') +def canonical(url): + (scheme, loc, path, params, q, fragment) = urlparse(url) + if not path: + path = '/' + if not loc: + loc, path = path, '' + if not scheme: + scheme = 'https' + return urlunparse((scheme, loc, path, params, q, fragment)) + + class IndieView(TemplateView): template_name = 'lemonauth/indie.html' required_params = ('me', 'client_id', 'redirect_uri') @method_decorator(login_required) + @method_decorator(render_to(template_name)) def get(self, request): - params = request.GET + params = request.GET.dict() + params.setdefault('response_type', 'id') + for param in self.required_params: if param not in params: return HttpResponseBadRequest( @@ -25,13 +41,9 @@ class IndieView(TemplateView): content_type='text/plain', ) - me = params['me'] - if me[-1] == '/': - me = me[:-1] - - origin = utils.origin(request) - user = urljoin(origin, request.user.url) - if user not in (me, me + '/'): + me = canonical(params['me']) + user = urljoin(utils.origin(request), request.user.url) + if user != me: return HttpResponseForbidden( 'you are logged in but not as {0}'.format(me), content_type='text/plain', @@ -52,8 +64,10 @@ class IndieView(TemplateView): except IndexError: app = None - return render(request, self.template_name, { - 'app': app, - 'params': params, - 'title': 'indieauth', - }) + return {'app': app, 'me': me, 'params': params, 'title': 'indieauth'} + + +@login_required +@require_POST +def approve(request): + return JsonResponse(request.POST)