diff --git a/README.md b/README.md index 9d04cc7..d9ea2ef 100644 --- a/README.md +++ b/README.md @@ -195,6 +195,7 @@ Don’t forget to point AUTH_USER_MODEL to it. Do this before creating any migra - [x] Use Custom authentication - needs to have a user! - [x] Implement creating new "User" - by POST / Model based +- [x] - [ ] Add tests for verify - [ ] Add tests for authentication - [ ] Add proper documentation @@ -211,6 +212,10 @@ Don’t forget to point AUTH_USER_MODEL to it. Do this before creating any migra ## Changelog +### 0.6, 2018-11-18 + +* Reuse TokenSerializer for VerifySerializer logic + ### 0.5, 2018-11-18 * Require authentication on all rest endpoints by token diff --git a/ungleichotp/otpauth/serializer.py b/ungleichotp/otpauth/serializer.py index d4acc14..dc5f131 100644 --- a/ungleichotp/otpauth/serializer.py +++ b/ungleichotp/otpauth/serializer.py @@ -13,57 +13,6 @@ class OTPSerializer(serializers.ModelSerializer): validated_data['seed'] = pyotp.random_base32() return OTPSeed.objects.create(**validated_data) -class VerifySerializerV1(serializers.Serializer): - """ - This is the first version of the serializer that would authenticate the request - itself. This is not necessary anymore starting from version 0.5 - - Code to be removed prior to 1.0 - """ - - name = serializers.CharField(max_length=128) - token = serializers.CharField(max_length=128) - realm = serializers.CharField(max_length=128) - - verifyname = serializers.CharField(max_length=128) - verifytoken = serializers.CharField(max_length=128) - verifyrealm = serializers.CharField(max_length=128) - - def save(self): - token_in = self.validated_data.get('token') - name_in = self.validated_data.get('name') - realm_in = self.validated_data.get('realm') - verifytoken = self.validated_data.get('verifytoken') - verifyname = self.validated_data.get('verifyname') - verifyrealm = self.validated_data.get('verifyrealm') - - # 1. Verify that the connection might authenticate - try: - db_instance = otpauth.models.OTPSeed.objects.get(name=name_in, realm=realm_in) - except (OTPSeed.MultipleObjectsReturned, OTPSeed.DoesNotExist): - raise exceptions.AuthenticationFailed() - - totp = pyotp.TOTP(db_instance.seed) - - if not totp.verify(token_in, valid_window=3): - raise exceptions.AuthenticationFailed() - - - # 2. Verify the requested data - try: - verifyinstance = otpauth.models.OTPSeed.objects.get(name=verifyname, realm=verifyrealm) - except (OTPSeed.MultipleObjectsReturned, OTPSeed.DoesNotExist): - raise exceptions.PermissionDenied() - - totp = pyotp.TOTP(verifyinstance.seed) - - if not totp.verify(verifytoken, valid_window=3): - raise exceptions.PermissionDenied() - - print("All verified!") - return verifyinstance - - class TokenSerializer(serializers.Serializer): name = serializers.CharField(max_length=128) token = serializers.CharField(max_length=128) @@ -78,7 +27,7 @@ class TokenSerializer(serializers.Serializer): name_in = self.validated_data.get(self.name_name) realm_in = self.validated_data.get(self.realm_name) - print("auth: {} {} {} ({} {} {} -- {})".format(token_in, name_in, realm_in, self.token_name, self.name_name, self.realm_name, self.validated_data)) + # print("auth: {} {} {} ({} {} {} -- {})".format(token_in, name_in, realm_in, self.token_name, self.name_name, self.realm_name, self.validated_data)) # 1. Verify that the connection might authenticate try: diff --git a/ungleichotp/otpauth/views.py b/ungleichotp/otpauth/views.py index dfe1f9a..234903b 100644 --- a/ungleichotp/otpauth/views.py +++ b/ungleichotp/otpauth/views.py @@ -1,17 +1,15 @@ from django.shortcuts import render from rest_framework import viewsets -from rest_framework.parsers import JSONParser from rest_framework.decorators import action from rest_framework.response import Response -from django.http import HttpResponse, JsonResponse - +from django.http import JsonResponse from otpauth.serializer import VerifySerializer, OTPSerializer from otpauth.models import OTPSeed -# Version 2 model - model based ++ verify action + class OTPVerifyViewSet(viewsets.ModelViewSet): serializer_class = OTPSerializer queryset = OTPSeed.objects.all() @@ -20,27 +18,8 @@ class OTPVerifyViewSet(viewsets.ModelViewSet): def verify(self, request): serializer = VerifySerializer(data=request.data) if serializer.is_valid(): - print(serializer) + # print(serializer) serializer.save() return Response({'status': 'OK'}) return JsonResponse(serializer.errors, status=400) - - -# Version 1 model - should be removed -class VerifyViewSet(viewsets.ViewSet): - serializer_class = VerifySerializer - - def create(self, request): - data = JSONParser().parse(request) - serializer = VerifySerializer(data=data) - if serializer.is_valid(): - print("is valid") - print(serializer) - #serializer.save() - return JsonResponse(serializer.data, status=201) - return JsonResponse(serializer.errors, status=400) - - - def get_queryset(self): - return [] diff --git a/ungleichotp/ungleichotp/urls.py b/ungleichotp/ungleichotp/urls.py index 8812180..5af3b02 100644 --- a/ungleichotp/ungleichotp/urls.py +++ b/ungleichotp/ungleichotp/urls.py @@ -14,19 +14,14 @@ Including another URLconf 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ - from django.contrib import admin from django.urls import path from django.conf.urls import url, include -from django.contrib.auth.models import User -from rest_framework import routers, serializers, viewsets -from otpauth.models import OTPSeed -from otpauth.views import OTPVerifyViewSet, VerifyViewSet - +from rest_framework import routers +from otpauth.views import OTPVerifyViewSet router = routers.DefaultRouter() -router.register(r'ungleichotp', VerifyViewSet, basename='ungleichotp') -router.register(r'ungleichotpv2', OTPVerifyViewSet, basename='ungleichotpv2') +router.register(r'ungleichotp', OTPVerifyViewSet, basename='ungleichotp') urlpatterns = [ path('admin/', admin.site.urls),