Implement the auth-code verification step, producing a complete IndieAuth implementation for 'id' type (nothing for 'code' type yet tho)

This commit is contained in:
Danielle McLean 2017-10-29 17:07:36 +11:00
parent 8b4a14ffa3
commit acce72e90e
Signed by: 00dani
GPG Key ID: 5A5D2D1AFF12EEC5
4 changed files with 47 additions and 1 deletions

View File

@ -30,6 +30,7 @@ django-push = "*"
pyyaml = "*" pyyaml = "*"
django-annoying = "*" django-annoying = "*"
django-shorturls = "*" django-shorturls = "*"
accept-types = "*"
[dev-packages] [dev-packages]

8
Pipfile.lock generated
View File

@ -1,7 +1,7 @@
{ {
"_meta": { "_meta": {
"hash": { "hash": {
"sha256": "3f9a75dcd0609cd38fc01d23b8f2e198e494f5ab7120e5bb8af08b909a16ea52" "sha256": "c9835b77b96ade2202ff84521a2cda6a3c04679d448cc434a49f3ce07d6befcf"
}, },
"host-environment-markers": { "host-environment-markers": {
"implementation_name": "cpython", "implementation_name": "cpython",
@ -27,6 +27,12 @@
] ]
}, },
"default": { "default": {
"accept-types": {
"hashes": [
"sha256:9ae86512bf3a3eaad6a2793617a34eb15b384593e6c28697bef9b15ac237017a"
],
"version": "==0.3.0"
},
"beautifulsoup4": { "beautifulsoup4": {
"hashes": [ "hashes": [
"sha256:7015e76bf32f1f574636c4288399a6de66ce08fb7b2457f628a8d70c0fbabb11", "sha256:7015e76bf32f1f574636c4288399a6de66ce08fb7b2457f628a8d70c0fbabb11",

View File

@ -3,9 +3,11 @@ import mf2py
from annoying.decorators import render_to from annoying.decorators import render_to
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.http import HttpResponseForbidden, HttpResponseBadRequest from django.http import HttpResponseForbidden, HttpResponseBadRequest
from django.http import JsonResponse
from django.shortcuts import redirect from django.shortcuts import redirect
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
from django.views.generic import TemplateView from django.views.generic import TemplateView
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_POST from django.views.decorators.http import require_POST
from lemoncurry import breadcrumbs, utils from lemoncurry import breadcrumbs, utils
from urllib.parse import urlencode, urljoin, urlunparse, urlparse from urllib.parse import urlencode, urljoin, urlunparse, urlparse
@ -26,6 +28,7 @@ def canonical(url):
return urlunparse((scheme, loc, path, params, q, fragment)) return urlunparse((scheme, loc, path, params, q, fragment))
@method_decorator(csrf_exempt, name='dispatch')
class IndieView(TemplateView): class IndieView(TemplateView):
template_name = 'lemonauth/indie.html' template_name = 'lemonauth/indie.html'
required_params = ('me', 'client_id', 'redirect_uri') required_params = ('me', 'client_id', 'redirect_uri')
@ -68,6 +71,25 @@ class IndieView(TemplateView):
return {'app': app, 'me': me, 'params': params, 'title': 'indieauth'} return {'app': app, 'me': me, 'params': params, 'title': 'indieauth'}
def post(self, request):
post = request.POST.dict()
try:
code = IndieAuthCode.objects.get(
code=post['code'],
client_id=post['client_id'],
redirect_uri=post['redirect_uri']
)
except IndieAuthCode.DoesNotExist:
return HttpResponseForbidden(
'invalid auth code {0}'.format(post['code']),
content_type='text/plain'
)
code.delete()
return utils.choose_type(request, {'me': code.me}, {
'application/json': JsonResponse,
'application/x-www-form-urlencoded': utils.form_encoded_response,
})
@login_required @login_required
@require_POST @require_POST

View File

@ -1,7 +1,10 @@
import json import json
from accept_types import get_best_match
from django.conf import settings from django.conf import settings
from django.http import HttpResponse
from os.path import join from os.path import join
from types import SimpleNamespace from types import SimpleNamespace
from urllib.parse import urlencode
cache = SimpleNamespace(package_json=None) cache = SimpleNamespace(package_json=None)
@ -20,3 +23,17 @@ def origin(request):
def uri(request): def uri(request):
return origin(request) + request.path return origin(request) + request.path
def choose_type(request, content, reps):
type = get_best_match(request.META.get('HTTP_ACCEPT'), reps.keys())
if type:
return reps[type](content)
return HttpResponse(status=406)
def form_encoded_response(content):
return HttpResponse(
urlencode(content),
content_type='application/x-www-form-urlencoded'
)