registration
[wolnelektury.git] / src / api / views.py
index 69f9b8b..0451c77 100644 (file)
@@ -1,22 +1,25 @@
-# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
-# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
+# This file is part of Wolne Lektury, licensed under GNU Affero GPLv3 or later.
+# Copyright © Fundacja Wolne Lektury. See NOTICE for more information.
 #
 #
+from time import time
+from django.contrib.auth import authenticate
 from django.contrib.auth.decorators import login_required
 from django.contrib.auth.decorators import login_required
+from django.contrib.auth.models import User
 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 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.common import urlencode, generate_token
 from oauthlib.oauth1 import RequestTokenEndpoint, AccessTokenEndpoint
 from oauthlib.oauth1 import AuthorizationEndpoint, OAuth1Error
 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
 from rest_framework.views import APIView
 from rest_framework.permissions import IsAuthenticated
 from rest_framework.response import Response
 from rest_framework.views import APIView
-from rest_framework.generics import ListAPIView, RetrieveAPIView, get_object_or_404
+from rest_framework.generics import GenericAPIView, RetrieveAPIView, get_object_or_404
 from catalogue.models import Book
 from catalogue.models import Book
-from .models import BookUserData
+from .models import BookUserData, KEY_SIZE, SECRET_SIZE, Token
+from social.models import UserConfirmation
 from . import serializers
 from .request_validator import PistonRequestValidator
 from .utils import oauthlib_request, oauthlib_response, vary_on_auth
 from . import serializers
 from .request_validator import PistonRequestValidator
 from .utils import oauthlib_request, oauthlib_response, vary_on_auth
@@ -76,7 +79,7 @@ def oauth_user_auth(request):
             realms, credentials = endpoint.get_realms_and_credentials(
                 **oauthlib_request(request))
         except OAuth1Error as e:
             realms, credentials = endpoint.get_realms_and_credentials(
                 **oauthlib_request(request))
         except OAuth1Error as e:
-            return HttpResponse(e.message, status=400)
+            return HttpResponse(str(e), status=400)
         callback = request.GET.get('oauth_callback')
 
         form = OAuthAuthenticationForm(initial={
         callback = request.GET.get('oauth_callback')
 
         form = OAuthAuthenticationForm(initial={
@@ -86,7 +89,7 @@ def oauth_user_auth(request):
 
         return render(request, 'oauth/authorize_token.html', {'form': form})
 
 
         return render(request, 'oauth/authorize_token.html', {'form': form})
 
-    elif request.method == "POST":
+    if request.method == "POST":
         try:
             response = oauthlib_response(
                 endpoint.create_authorization_response(
         try:
             response = oauthlib_response(
                 endpoint.create_authorization_response(
@@ -132,6 +135,59 @@ class OAuth1AccessTokenView(View):
         )
 
 
         )
 
 
+class LoginView(GenericAPIView):
+    serializer_class = serializers.LoginSerializer
+
+    def post(self, request):
+        serializer = self.get_serializer(data=request.data)
+        serializer.is_valid(raise_exception=True)
+        d = serializer.validated_data
+        user = authenticate(username=d['username'], password=d['password'])
+        if user is None:
+            return Response({"detail": "Invalid credentials."})
+
+        key = generate_token()[:KEY_SIZE]
+        Token.objects.create(
+            key=key,
+            token_type=Token.ACCESS,
+            timestamp=time(),
+            user=user,
+        )
+        return Response({"access_token": key})
+
+
+class Login2View(GenericAPIView):
+    serializer_class = serializers.LoginSerializer
+
+    def post(self, request):
+        serializer = self.get_serializer(data=request.data)
+        serializer.is_valid(raise_exception=True)
+        d = serializer.validated_data
+        user = authenticate(username=d['username'], password=d['password'])
+        if user is None:
+            return Response({"detail": "Invalid credentials."})
+
+        access_token = generate_token()[:KEY_SIZE]
+        Token.objects.create(
+            key=access_token,
+            token_type=Token.ACCESS,
+            timestamp=time(),
+            user=user,
+        )
+        refresh_token = generate_token()[:KEY_SIZE]
+        Token.objects.create(
+            key=refresh_token,
+            token_type=Token.REFRESH,
+            timestamp=time(),
+            user=user,
+        )
+        return Response({
+            "access_token": access_token,
+            "refresh_token": refresh_token,
+            "expires": 3600,
+        })
+
+
 @vary_on_auth
 class UserView(RetrieveAPIView):
     permission_classes = [IsAuthenticated]
 @vary_on_auth
 class UserView(RetrieveAPIView):
     permission_classes = [IsAuthenticated]
@@ -170,3 +226,103 @@ class BookUserDataView(RetrieveAPIView):
 class BlogView(APIView):
     def get(self, request):
         return Response([])
 class BlogView(APIView):
     def get(self, request):
         return Response([])
+
+
+
+class RegisterView(GenericAPIView):
+    serializer_class = serializers.RegisterSerializer
+
+    def get(self, request):
+        return Response({
+            "options": [
+                {
+                    "id": 1,
+                    "html": "Chcę otrzymywać newsletter Wolnych Lektur",
+                    "required": False
+                }
+            ],
+            "info": [
+                'Administratorem danych osobowych jest Fundacja Wolne Lektury (ul. Marszałkowska 84/92 lok. 125, 00-514 Warszawa). Podanie danych osobowych jest dobrowolne. Dane są przetwarzane w zakresie niezbędnym do prowadzenia serwisu, a także w celach prowadzenia statystyk, ewaluacji i sprawozdawczości. W przypadku wyrażenia dodatkowej zgody adres e-mail zostanie wykorzystany także w celu przesyłania newslettera Wolnych Lektur. Osobom, których dane są zbierane, przysługuje prawo dostępu do treści swoich danych oraz ich poprawiania. Więcej informacji w <a href="https://fundacja.wolnelektury.pl/prywatnosc/">polityce prywatności</a>.'
+            ]            
+        })
+
+    def post(self, request):
+        serializer = self.get_serializer(data=request.data)
+        serializer.is_valid(raise_exception=True)
+        d = serializer.validated_data
+
+        user = User(
+            username=d['email'],
+            email=d['email'],
+            is_active=False
+        )
+        user.set_password(d['password'])
+
+        try:
+            user.save()
+        except:
+            return Response(
+                {
+                    "detail": "Nie można utworzyć konta.",
+                },
+                status=400
+            )
+
+        UserConfirmation.request(user)
+        return Response({})
+
+
+class RefreshTokenView(APIView):
+    serializer_class = serializers.RefreshTokenSerializer
+
+    def post(self, request):
+        serializer = self.get_serializer(data=request.data)
+        serializer.is_valid(raise_exception=True)
+        d = serializer.validated_data
+        
+        t = Token.objects.get(
+            key=d['refresh_token'],
+            token_type=Token.REFRESH
+        )
+        user = t.user
+
+        access_token = generate_token()[:KEY_SIZE]
+        Token.objects.create(
+            key=access_token,
+            token_type=Token.ACCESS,
+            timestamp=time(),
+            user=user,
+        )
+        refresh_token = generate_token()[:KEY_SIZE]
+        Token.objects.create(
+            key=refresh_token,
+            token_type=Token.REFRESH,
+            timestamp=time(),
+            user=user,
+        )
+        return Response({
+            "access_token": access_token,
+            "refresh_token": refresh_token,
+            "expires": 3600,
+        })
+
+
+class RequestConfirmView(APIView):
+    serializer_class = serializers.RequestConfirmSerializer
+
+    def post(self, request):
+        serializer = self.get_serializer(data=request.data)
+        serializer.is_valid(raise_exception=True)
+        d = serializer.validated_data
+
+        try:
+            user = User.objects.get(
+                username=d['email'],
+                is_active=False
+            )
+        except User.DoesNotExist:
+            raise Http404
+
+        UserConfirmation.request(user)
+        return Response({})
+