Allow uploading audiobooks via API.
[wolnelektury.git] / src / api / views.py
index 377beb6..f28a4e4 100644 (file)
@@ -3,6 +3,10 @@
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 from django.http import Http404
+from django.views.generic.base import View
+from oauthlib.common import urlencode
+from oauthlib.oauth1 import RequestTokenEndpoint, AccessTokenEndpoint
+from api.piston.models import KEY_SIZE, SECRET_SIZE
 from rest_framework.permissions import IsAuthenticated
 from rest_framework.response import Response
 from rest_framework.views import APIView
@@ -11,8 +15,72 @@ from migdal.models import Entry
 from catalogue.models import Book
 from .models import BookUserData
 from . import serializers
+from .request_validator import PistonRequestValidator
+from .utils import oauthlib_request, oauthlib_response, vary_on_auth
 
 
+class OAuth1RequestTokenEndpoint(RequestTokenEndpoint):
+    def _create_request(self, *args, **kwargs):
+        r = super(OAuth1RequestTokenEndpoint, self)._create_request(*args, **kwargs)
+        r.redirect_uri = 'oob'
+        return r
+
+    def create_request_token(self, request, credentials):
+        token = {
+            'oauth_token': self.token_generator()[:KEY_SIZE],
+            'oauth_token_secret': self.token_generator()[:SECRET_SIZE],
+        }
+        token.update(credentials)
+        self.request_validator.save_request_token(token, request)
+        return urlencode(token.items())
+
+
+# Never Cache
+class OAuth1RequestTokenView(View):
+    def __init__(self):
+        self.endpoint = OAuth1RequestTokenEndpoint(PistonRequestValidator())
+
+    def dispatch(self, request):
+        return oauthlib_response(
+            self.endpoint.create_request_token_response(
+                **oauthlib_request(request)
+            )
+        )
+
+
+class OAuth1AccessTokenEndpoint(AccessTokenEndpoint):
+    def _create_request(self, *args, **kwargs):
+        r = super(OAuth1AccessTokenEndpoint, self)._create_request(*args, **kwargs)
+        r.verifier = 'x' * 20
+        return r
+
+    def create_access_token(self, request, credentials):
+        request.realms = self.request_validator.get_realms(
+            request.resource_owner_key, request)
+        token = {
+            'oauth_token': self.token_generator()[:KEY_SIZE],
+            'oauth_token_secret': self.token_generator()[:SECRET_SIZE],
+            'oauth_authorized_realms': ' '.join(request.realms)
+        }
+        token.update(credentials)
+        self.request_validator.save_access_token(token, request)
+        return urlencode(token.items())
+
+
+# Never cache
+class OAuth1AccessTokenView(View):
+    def __init__(self):
+        self.endpoint = OAuth1AccessTokenEndpoint(PistonRequestValidator())
+
+    def dispatch(self, request):
+        return oauthlib_response(
+            self.endpoint.create_access_token_response(
+                **oauthlib_request(request)
+            )
+        )
+
+
+@vary_on_auth
 class UserView(RetrieveAPIView):
     permission_classes = [IsAuthenticated]
     serializer_class = serializers.UserSerializer
@@ -21,6 +89,7 @@ class UserView(RetrieveAPIView):
         return self.request.user
 
 
+@vary_on_auth
 class BookUserDataView(RetrieveAPIView):
     permission_classes = [IsAuthenticated]
     serializer_class = serializers.BookUserDataSerializer