from django.contrib.auth.models import User from rest_framework import authentication, exceptions, serializers import urllib.request import pyotp import json # For parsing class TokenSerializer(serializers.Serializer): name = serializers.CharField(max_length=128) token = serializers.CharField(max_length=128) realm = serializers.CharField(max_length=128) token_name = 'token' name_name = 'name' realm_name = 'realm' def __init__(self, name, realm, seed, serverurl, *args, **kwargs): self.name = name self.realm = realm self.seed = seed self.serverurl = serverurl super(serializers.Serializer, self).__init__(*args, **kwargs) def save(self): to_send = {} # Client credentials to be verified to_send['verifytoken'] = self.validated_data.get(self.token_name) to_send['verifyname'] = self.validated_data.get(self.name_name) to_send['verifyrealm'] = self.validated_data.get(self.real_name) # Our credentials to_send['token'] = pyotp.TOTP(self.seed) to_send['name'] = self.name to_send['realm'] = self.realm data = json.dumps(to_send).encode("utf-8") req = urllib.request.Request(url=serverurl, data=data, headers={'Content-Type': 'application/json'}, method='POST') f = urllib.request.urlopen(req) if not f.status == 200: raise exceptions.AuthenticationFailed() return True class OTPAuthentication(authentication.BaseAuthentication): def authenticate(self, request): serializer = TokenSerializer(data=request.data) if serializer.is_valid(): print("trying to save... {}".format(serializer)) user, token = serializer.save() else: raise exceptions.AuthenticationFailed() return (user, token)