From 10dc1a5e84d23582a58ead2551ddf54a66b94496 Mon Sep 17 00:00:00 2001 From: Radek Czajka Date: Fri, 1 Mar 2019 00:08:21 +0100 Subject: [PATCH] Remove piston residue. --- .../0005_consumer_nonce_resource_token.py | 7 +- src/api/piston/__init__.py | 0 src/api/piston/migrations/0001_initial.py | 58 ----------------- .../migrations/0002_auto_20190228_2338.py | 52 --------------- src/api/piston/migrations/__init__.py | 0 src/api/piston/models.py | 0 src/api/piston_patch.py | 64 ------------------- .../templates/oauth}/authorize_token.html | 0 src/api/urls.py | 3 +- src/api/utils.py | 6 +- src/api/views.py | 54 ++++++++++++++++ src/paypal/views.py | 2 +- src/wolnelektury/settings/apps.py | 1 - 13 files changed, 62 insertions(+), 185 deletions(-) delete mode 100644 src/api/piston/__init__.py delete mode 100644 src/api/piston/migrations/0001_initial.py delete mode 100644 src/api/piston/migrations/0002_auto_20190228_2338.py delete mode 100644 src/api/piston/migrations/__init__.py delete mode 100644 src/api/piston/models.py delete mode 100644 src/api/piston_patch.py rename src/{wolnelektury/templates/piston => api/templates/oauth}/authorize_token.html (100%) diff --git a/src/api/migrations/0005_consumer_nonce_resource_token.py b/src/api/migrations/0005_consumer_nonce_resource_token.py index 95873a7e3..713220350 100644 --- a/src/api/migrations/0005_consumer_nonce_resource_token.py +++ b/src/api/migrations/0005_consumer_nonce_resource_token.py @@ -12,10 +12,9 @@ class Migration(migrations.Migration): dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), ('api', '0004_bookuserdata_last_changed'), - ('piston', '0002_auto_20190228_2338'), ] - state_operations = [ + operations = [ migrations.CreateModel( name='Consumer', fields=[ @@ -51,7 +50,3 @@ class Migration(migrations.Migration): ], ), ] - - operations = [ - migrations.SeparateDatabaseAndState(state_operations=state_operations), - ] diff --git a/src/api/piston/__init__.py b/src/api/piston/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/api/piston/migrations/0001_initial.py b/src/api/piston/migrations/0001_initial.py deleted file mode 100644 index c2939b19a..000000000 --- a/src/api/piston/migrations/0001_initial.py +++ /dev/null @@ -1,58 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import migrations, models -from django.conf import settings - - -class Migration(migrations.Migration): - - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ] - - operations = [ - migrations.CreateModel( - name='Consumer', - fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('name', models.CharField(max_length=255)), - ('description', models.TextField()), - ('key', models.CharField(max_length=18)), - ('secret', models.CharField(max_length=32)), - ('status', models.CharField(default=b'pending', max_length=16, choices=[(b'pending', b'Pending approval'), (b'accepted', b'Accepted'), (b'canceled', b'Canceled')])), - ('user', models.ForeignKey(related_name='consumers', blank=True, to=settings.AUTH_USER_MODEL, null=True)), - ], - ), - migrations.CreateModel( - name='Nonce', - fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('token_key', models.CharField(max_length=18)), - ('consumer_key', models.CharField(max_length=18)), - ('key', models.CharField(max_length=255)), - ], - ), - migrations.CreateModel( - name='Resource', - fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('name', models.CharField(max_length=255)), - ('url', models.TextField(max_length=2047)), - ('is_readonly', models.BooleanField(default=True)), - ], - ), - migrations.CreateModel( - name='Token', - fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('key', models.CharField(max_length=18)), - ('secret', models.CharField(max_length=32)), - ('token_type', models.IntegerField(choices=[(1, 'Request'), (2, 'Access')])), - ('timestamp', models.IntegerField()), - ('is_approved', models.BooleanField(default=False)), - ('consumer', models.ForeignKey(to='piston.Consumer')), - ('user', models.ForeignKey(related_name='tokens', blank=True, to=settings.AUTH_USER_MODEL, null=True)), - ], - ), - ] diff --git a/src/api/piston/migrations/0002_auto_20190228_2338.py b/src/api/piston/migrations/0002_auto_20190228_2338.py deleted file mode 100644 index 4fa2b9057..000000000 --- a/src/api/piston/migrations/0002_auto_20190228_2338.py +++ /dev/null @@ -1,52 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.20 on 2019-02-28 22:38 -from __future__ import unicode_literals - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('piston', '0001_initial'), - ] - - database_operations = [ - migrations.AlterModelTable('Nonce', 'api_nonce'), - migrations.AlterModelTable('Consumer', 'api_consumer'), - migrations.AlterModelTable('Token', 'api_token'), - ] - - state_operations = [ - migrations.RemoveField( - model_name='consumer', - name='user', - ), - migrations.DeleteModel( - name='Nonce', - ), - migrations.RemoveField( - model_name='token', - name='consumer', - ), - migrations.RemoveField( - model_name='token', - name='user', - ), - migrations.DeleteModel( - name='Consumer', - ), - migrations.DeleteModel( - name='Token', - ), - ] - - operations = [ - migrations.SeparateDatabaseAndState( - database_operations=database_operations, - state_operations=state_operations - ), - migrations.DeleteModel( - name='Resource', - ), - ] diff --git a/src/api/piston/migrations/__init__.py b/src/api/piston/migrations/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/api/piston/models.py b/src/api/piston/models.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/api/piston_patch.py b/src/api/piston_patch.py deleted file mode 100644 index 6a80e15cd..000000000 --- a/src/api/piston_patch.py +++ /dev/null @@ -1,64 +0,0 @@ -# -*- coding: utf-8 -*- -# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later. -# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. -# -from oauthlib.oauth1 import AuthorizationEndpoint, OAuth1Error -from django.contrib.auth.decorators import login_required -from django import forms -from django.http import HttpResponse, HttpResponseRedirect -from django.shortcuts import render -from .request_validator import PistonRequestValidator -from .utils import oauthlib_request, oauthlib_response - - -class HttpResponseAppRedirect(HttpResponseRedirect): - allowed_schemes = HttpResponseRedirect.allowed_schemes + ['wolnelekturyapp'] - - -class OAuthAuthenticationForm(forms.Form): - oauth_token = forms.CharField(widget=forms.HiddenInput) - oauth_callback = forms.CharField(widget=forms.HiddenInput) # changed from URLField - too strict - # removed authorize_access - redundant - - -class OAuth1AuthorizationEndpoint(AuthorizationEndpoint): - def create_verifier(self, request, credentials): - verifier = super(OAuth1AuthorizationEndpoint, self).create_verifier(request, credentials) - return { - 'oauth_token': verifier['oauth_token'], - } - - -@login_required -def oauth_user_auth(request): - endpoint = OAuth1AuthorizationEndpoint(PistonRequestValidator()) - - if request.method == "GET": - # Why not just get oauth_token here? - # This is fairly straightforward, in't? - try: - realms, credentials = endpoint.get_realms_and_credentials( - **oauthlib_request(request)) - except OAuth1Error as e: - return HttpResponse(e.message, status=400) - callback = request.GET.get('oauth_callback') - - form = OAuthAuthenticationForm(initial={ - 'oauth_token': credentials['resource_owner_key'], - 'oauth_callback': callback, - }) - - return render(request, 'piston/authorize_token.html', {'form': form}) - - elif request.method == "POST": - try: - response = oauthlib_response( - endpoint.create_authorization_response( - credentials={"user": request.user}, - **oauthlib_request(request) - ) - ) - except OAuth1Error as e: - return HttpResponse(e.message, status=400) - else: - return response diff --git a/src/wolnelektury/templates/piston/authorize_token.html b/src/api/templates/oauth/authorize_token.html similarity index 100% rename from src/wolnelektury/templates/piston/authorize_token.html rename to src/api/templates/oauth/authorize_token.html diff --git a/src/api/urls.py b/src/api/urls.py index 5ebe3a36f..a3e877d6c 100644 --- a/src/api/urls.py +++ b/src/api/urls.py @@ -7,13 +7,12 @@ from django.views.decorators.csrf import csrf_exempt from django.views.generic import TemplateView import catalogue.views from stats.utils import piwik_track_view -from api.piston_patch import oauth_user_auth from . import views urlpatterns = [ url(r'^oauth/request_token/$', views.OAuth1RequestTokenView.as_view()), - url(r'^oauth/authorize/$', oauth_user_auth, name='oauth_user_auth'), + url(r'^oauth/authorize/$', views.oauth_user_auth, name='oauth_user_auth'), url(r'^oauth/access_token/$', csrf_exempt(views.OAuth1AccessTokenView.as_view())), url(r'^$', TemplateView.as_view(template_name='api/main.html'), name='api'), diff --git a/src/api/utils.py b/src/api/utils.py index 045ce90e9..c9c1f94cc 100644 --- a/src/api/utils.py +++ b/src/api/utils.py @@ -2,7 +2,7 @@ # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later. # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. # -from django.http import HttpResponse +from django.http import HttpResponse, HttpResponseRedirect from django.utils.decorators import method_decorator from django.utils.encoding import iri_to_uri from django.views.decorators.vary import vary_on_headers @@ -36,3 +36,7 @@ def oauthlib_response((headers, body, status)): vary_on_auth = method_decorator(vary_on_headers('Authorization'), 'dispatch') + + +class HttpResponseAppRedirect(HttpResponseRedirect): + allowed_schemes = HttpResponseRedirect.allowed_schemes + ['wolnelekturyapp'] diff --git a/src/api/views.py b/src/api/views.py index 741e45420..5df3d689d 100644 --- a/src/api/views.py +++ b/src/api/views.py @@ -2,10 +2,15 @@ # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later. # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. # +from django.contrib.auth.decorators import login_required +from django import forms +from django.http import HttpResponse from django.http import Http404 +from django.shortcuts import render from django.views.generic.base import View from oauthlib.common import urlencode from oauthlib.oauth1 import RequestTokenEndpoint, AccessTokenEndpoint +from oauthlib.oauth1 import AuthorizationEndpoint, OAuth1Error from api.models import KEY_SIZE, SECRET_SIZE from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response @@ -48,6 +53,55 @@ class OAuth1RequestTokenView(View): ) +class OAuthAuthenticationForm(forms.Form): + oauth_token = forms.CharField(widget=forms.HiddenInput) + oauth_callback = forms.CharField(widget=forms.HiddenInput) # changed from URLField - too strict + # removed authorize_access - redundant + + +class OAuth1AuthorizationEndpoint(AuthorizationEndpoint): + def create_verifier(self, request, credentials): + verifier = super(OAuth1AuthorizationEndpoint, self).create_verifier(request, credentials) + return { + 'oauth_token': verifier['oauth_token'], + } + + +@login_required +def oauth_user_auth(request): + endpoint = OAuth1AuthorizationEndpoint(PistonRequestValidator()) + + if request.method == "GET": + # Why not just get oauth_token here? + # This is fairly straightforward, in't? + try: + realms, credentials = endpoint.get_realms_and_credentials( + **oauthlib_request(request)) + except OAuth1Error as e: + return HttpResponse(e.message, status=400) + callback = request.GET.get('oauth_callback') + + form = OAuthAuthenticationForm(initial={ + 'oauth_token': credentials['resource_owner_key'], + 'oauth_callback': callback, + }) + + return render(request, 'oauth/authorize_token.html', {'form': form}) + + elif request.method == "POST": + try: + response = oauthlib_response( + endpoint.create_authorization_response( + credentials={"user": request.user}, + **oauthlib_request(request) + ) + ) + except OAuth1Error as e: + return HttpResponse(e.message, status=400) + else: + return response + + class OAuth1AccessTokenEndpoint(AccessTokenEndpoint): def _create_request(self, *args, **kwargs): r = super(OAuth1AccessTokenEndpoint, self)._create_request(*args, **kwargs) diff --git a/src/paypal/views.py b/src/paypal/views.py index e46be8ce6..c78a19af3 100644 --- a/src/paypal/views.py +++ b/src/paypal/views.py @@ -9,7 +9,7 @@ from django.http import Http404 from django.http.response import HttpResponseRedirect, HttpResponseForbidden from django.shortcuts import render -from api.piston_patch import HttpResponseAppRedirect +from api.utils import HttpResponseAppRedirect from paypal.forms import PaypalSubscriptionForm from paypal.rest import execute_agreement, check_agreement, agreement_approval_url, PaypalError from paypal.models import BillingAgreement, BillingPlan diff --git a/src/wolnelektury/settings/apps.py b/src/wolnelektury/settings/apps.py index c98944b39..07f7ff1fc 100644 --- a/src/wolnelektury/settings/apps.py +++ b/src/wolnelektury/settings/apps.py @@ -50,7 +50,6 @@ INSTALLED_APPS_CONTRIB = [ 'rest_framework', 'fnp_django_pagination', 'pipeline', - 'api.piston', 'piwik', 'sorl.thumbnail', 'kombu.transport.django', -- 2.20.1