ungleich-otp/otpauth/serializer.py

81 lines
2.7 KiB
Python

import pyotp
import otpauth
from rest_framework import serializers, exceptions
from otpauth.models import OTPSeed
# For accessing / modifying the data -- currently unused
class OTPSerializer(serializers.ModelSerializer):
class Meta:
model = OTPSeed
fields = ('name', 'realm', 'seed')
read_only_fields = ('seed',)
def create(self, validated_data):
validated_data['seed'] = pyotp.random_base32()
return OTPSeed.objects.create(**validated_data)
class TokenSerializer(serializers.Serializer):
name = serializers.CharField(max_length=128)
realm = serializers.CharField(max_length=128)
auth_name = serializers.CharField(max_length=128)
auth_token = serializers.CharField(max_length=128)
auth_realm = serializers.CharField(max_length=128)
def create(self, validated_data):
print("Trying to create")
validated_data['seed'] = pyotp.random_base32()
return OTPSeed.objects.create(**validated_data)
def update(self, instance, validated_data):
print("Trying to update")
instance.name = validated_data.get('name', instance.name)
instance.realm = validated_data.get('realm', instance.realm)
instance.save()
return instance
def save(self):
name_in = self.validated_data.get("name")
realm_in = self.validated_data.get("realm")
auth_token = self.validated_data.get("auth_token")
auth_name = self.validated_data.get("auth_name")
auth_realm = self.validated_data.get("auth_realm")
print("auth: {}@'{}' {} + {})".format(auth_name, auth_realm, auth_token, self.validated_data))
# 1. Verify that the connection might authenticate
try:
db_instance = otpauth.models.OTPSeed.objects.get(name=auth_name, realm=auth_realm)
except (OTPSeed.MultipleObjectsReturned, OTPSeed.DoesNotExist):
print("does not exist")
raise exceptions.AuthenticationFailed()
totp = pyotp.TOTP(db_instance.seed)
print("calculated token = {}".format(totp.now()))
if not totp.verify(auth_token, valid_window=3):
raise exceptions.AuthenticationFailed()
return (db_instance, auth_token)
# For verifying a token
class VerifySerializer(TokenSerializer):
verifyname = serializers.CharField(max_length=128)
verifytoken = serializers.CharField(max_length=128)
verifyrealm = serializers.CharField(max_length=128)
token_name = 'verifytoken'
name_name = 'verifyname'
realm_name = 'verifyrealm'
# token_name = 'token'
# name_name = 'name'
# realm_name = 'realm'
# auth_token_name = 'auth_token'
# auth_name_name = 'auth_name'
# auth_realm_name = 'auth_realm'