django-cryptolock/django_cryptolock/views.py

76 lines
2.6 KiB
Python
Raw Normal View History

# -*- coding: utf-8 -*-
from django.utils.translation import gettext_lazy as _
2019-11-17 23:27:40 +01:00
from django.contrib.auth.views import LoginView
from django.contrib.auth import get_user_model
2019-11-17 23:27:40 +01:00
from django.views.generic import FormView
from django.forms.utils import ErrorList
from django.conf import settings
from monerorpc.authproxy import JSONRPCException
from .forms import SimpleSignUpForm, SimpleLoginForm
2020-03-10 16:00:11 +01:00
from .utils import verify_monero_signature, verify_bitcoin_signature
from .models import Address, Challenge
2019-11-17 23:27:40 +01:00
2020-03-10 16:00:11 +01:00
class CryptoLockLoginView(LoginView):
template_name = "django_cryptolock/login.html"
form_class = SimpleLoginForm
2019-11-17 23:27:40 +01:00
def form_valid(self, form):
response = super().form_valid(form)
challenge = form.cleaned_data["challenge"]
Challenge.objects.invalidate(challenge)
Challenge.objects.clean_expired()
return response
2019-11-17 23:27:40 +01:00
2020-03-10 16:00:11 +01:00
class CryptoLockSignUpView(FormView):
template_name = "django_cryptolock/signup.html"
2019-11-25 14:23:55 +01:00
form_class = SimpleSignUpForm
def get_form(self, form_class=None):
return self.form_class(request=self.request, **self.get_form_kwargs())
def form_valid(self, form):
try:
2020-03-31 14:59:07 +02:00
valid_sig = self.verify_signature(form)
except JSONRPCException:
2020-03-31 14:59:07 +02:00
form._errors["__all__"] = ErrorList(
[_("Error connecting to Monero daemon")]
)
return self.form_invalid(form)
2020-03-10 16:00:11 +01:00
username = form.cleaned_data["username"]
address = form.cleaned_data["address"]
challenge = form.cleaned_data["challenge"]
2020-03-10 16:00:11 +01:00
if valid_sig:
user = get_user_model().objects.create(username=username)
2020-03-31 14:59:07 +02:00
user.address_set.create(address=address, network=form.network)
Challenge.objects.invalidate(challenge)
return super().form_valid(form)
else:
form._errors["signature"] = ErrorList([_("Invalid signature")])
return self.form_invalid(form)
def get_success_url(self):
return settings.LOGIN_REDIRECT_URL
2020-03-10 16:00:11 +01:00
def verify_signature(self, form):
address = form.cleaned_data["address"]
challenge = form.cleaned_data["challenge"]
signature = form.cleaned_data["signature"]
2020-03-31 14:59:07 +02:00
bitcoin = form.network == Address.NETWORK_BITCOIN
monero = form.network == Address.NETWORK_MONERO
2020-03-10 16:00:11 +01:00
valid_sig = False
2020-03-31 14:59:07 +02:00
if bitcoin:
2020-03-10 16:00:11 +01:00
valid_sig = verify_bitcoin_signature(
address, challenge, signature, request=self.request
)
2020-03-31 14:59:07 +02:00
elif monero:
2020-03-10 16:00:11 +01:00
valid_sig = verify_monero_signature(address, challenge, signature)
2020-03-31 14:59:07 +02:00
return valid_sig